From 27c557058699827bca48a087d0fcb7dfc8ced94c Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Thu, 1 Sep 2022 13:04:08 +0100 Subject: [PATCH] Rudimentary syntax work for dialogue --- .../supervisor-module/Chapter 2/Copy Errors.w | 4 + .../Chapter 5/Project Services.w | 1 + .../supervisor-module/Chapter 6/Headings.w | 18 +++++ .../supervisor-module/Chapter 6/Source Text.w | 3 + .../PM_DialogueOnSectionsOnly.txt | 5 ++ .../Test Problems/PM_UnexpectedDialogue.txt | 13 ++++ .../PM_DialogueOnSectionsOnly.txt | 10 +++ .../_Results_Ideal/PM_UnexpectedDialogue.txt | 11 +++ .../Chapter 2/Passes through Major Nodes.w | 3 + inform7/core-module/Chapter 1/Core Module.w | 7 +- .../Chapter 2/Problems With Source Text.w | 19 +++++ .../arch-module/Chapter 3/Feature Manager.w | 13 ++++ .../_Results_Ideal/recursive-bad-trace.txt | 2 +- services/syntax-module/Chapter 2/Node Types.w | 24 +++--- services/syntax-module/Chapter 3/Sentences.w | 74 +++++++++++++++---- .../syntax-test/Chapter 1/Program Control.w | 4 + services/syntax-test/Chapter 1/Unit Tests.w | 9 ++- .../Test Cases/_Results_Ideal/dialogue.txt | 9 +++ .../Tests/Test Cases/_Results_Ideal/tree.txt | 4 +- .../syntax-test/Tests/Test Cases/dialogue.txt | 11 +++ 20 files changed, 210 insertions(+), 34 deletions(-) create mode 100644 inform7/Tests/Test Problems/PM_DialogueOnSectionsOnly.txt create mode 100644 inform7/Tests/Test Problems/PM_UnexpectedDialogue.txt create mode 100644 inform7/Tests/Test Problems/_Results_Ideal/PM_DialogueOnSectionsOnly.txt create mode 100644 inform7/Tests/Test Problems/_Results_Ideal/PM_UnexpectedDialogue.txt create mode 100644 services/syntax-test/Tests/Test Cases/_Results_Ideal/dialogue.txt create mode 100644 services/syntax-test/Tests/Test Cases/dialogue.txt diff --git a/inbuild/supervisor-module/Chapter 2/Copy Errors.w b/inbuild/supervisor-module/Chapter 2/Copy Errors.w index 447bfd756..75c383a01 100644 --- a/inbuild/supervisor-module/Chapter 2/Copy Errors.w +++ b/inbuild/supervisor-module/Chapter 2/Copy Errors.w @@ -219,6 +219,10 @@ void CopyErrors::write(OUTPUT_STREAM, copy_error *CE) { WRITE("heading is in place of another heading which doesn't exist"); break; case UnavailableLOS_SYNERROR: WRITE("this language bundle does not provide Preform syntax"); break; + case DialogueOnSectionsOnly_SYNERROR: + WRITE("only 'Section' headings can be marked as '(dialogue)'"); break; + case UnexpectedDialogue_SYNERROR: + WRITE("something other than a cue or a line under a dialogue heading"); break; default: WRITE("syntax error"); break; } diff --git a/inbuild/supervisor-module/Chapter 5/Project Services.w b/inbuild/supervisor-module/Chapter 5/Project Services.w index 29c1b6898..e14065964 100644 --- a/inbuild/supervisor-module/Chapter 5/Project Services.w +++ b/inbuild/supervisor-module/Chapter 5/Project Services.w @@ -995,6 +995,7 @@ it comes. int l = SyntaxTree::push_bud(proj->syntax_tree, proj->syntax_tree->root_node); Sentences::break_into_project_copy( proj->syntax_tree, Wordings::new(wc, lexer_wordcount-1), proj->as_copy, proj); +LOG("Heya!\n$T\n", proj->syntax_tree->root_node); SyntaxTree::pop_bud(proj->syntax_tree, l); @ Inventions are when the //inform7// compiler makes up extra sentences, not diff --git a/inbuild/supervisor-module/Chapter 6/Headings.w b/inbuild/supervisor-module/Chapter 6/Headings.w index efd898239..3682f19af 100644 --- a/inbuild/supervisor-module/Chapter 6/Headings.w +++ b/inbuild/supervisor-module/Chapter 6/Headings.w @@ -146,6 +146,7 @@ typedef struct heading { int for_release; /* include this material in a release version? */ int omit_material; /* if set, simply ignore all of this */ int use_with_or_without; /* if TRUE, use with the extension; if FALSE, without */ + int holds_dialogue; /* if TRUE, contains dialogue in a different format */ struct inbuild_work *for_use_with; /* e.g. "for use with ... by ..." */ struct wording in_place_of_text; /* e.g. "in place of ... in ... by ..." */ struct wording heading_text; /* once provisos have been stripped away */ @@ -175,6 +176,7 @@ heading *Headings::new(parse_node_tree *T, parse_node *pn, int level, source_loc h->in_place_of_text = EMPTY_WORDING; h->for_use_with = NULL; h->sentence_declaring = pn; + h->holds_dialogue = FALSE; h->start_location = sl; h->level = level; h->heading_text = EMPTY_WORDING; @@ -262,6 +264,7 @@ heading *Headings::attach(parse_node_tree *T, parse_node *pn) { @d USE_WITH_HQ 5 @d USE_WITHOUT_HQ 6 @d IN_PLACE_OF_HQ 7 +@d DIALOGUE_HQ 8 @ = current_sentence = pn; @@ -275,6 +278,14 @@ heading *Headings::attach(parse_node_tree *T, parse_node *pn) { case UNINDEXED_HQ: h->index_definitions_made_under_this = FALSE; break; case USE_WITH_HQ: h->use_with_or_without = TRUE; break; case USE_WITHOUT_HQ: h->use_with_or_without = FALSE; break; + case DIALOGUE_HQ: + if (h->level != 5) { + copy_error *CE = CopyErrors::new(SYNTAX_CE, DialogueOnSectionsOnly_SYNERROR); + CopyErrors::supply_node(CE, current_sentence); + Copies::attach_error(sfsm->ref, CE); + } + h->holds_dialogue = TRUE; + break; case IN_PLACE_OF_HQ: h->use_with_or_without = TRUE; h->in_place_of_text = GET_RW(, 1); @@ -296,6 +307,11 @@ would match twice, first registering the VM requirement, then the unindexedness. It's an unfortunate historical quirk that the unbracketed qualifiers are allowed; they should probably be withdrawn. +Properly speaking the annotation "(dialogue)" should be recognised only if +the dialogue feature is active, but there are timing reasons not to do this: +headings are parsed before the set of active compiler features for a project +is determined. + = ::= ... ( ) | ==> { pass 1 } @@ -307,6 +323,8 @@ allowed; they should probably be withdrawn. not for release | ==> { NOT_FOR_RELEASE_HQ, - } for release only | ==> { FOR_RELEASE_ONLY_HQ, - } unindexed | ==> { UNINDEXED_HQ, - } + dialogue | ==> { DIALOGUE_HQ, - } + dialog | ==> { DIALOGUE_HQ, - } | ==> { pass 1 } ==> { pass 1 } diff --git a/inbuild/supervisor-module/Chapter 6/Source Text.w b/inbuild/supervisor-module/Chapter 6/Source Text.w index d88e8dc23..0309fb282 100644 --- a/inbuild/supervisor-module/Chapter 6/Source Text.w +++ b/inbuild/supervisor-module/Chapter 6/Source Text.w @@ -149,6 +149,7 @@ add to those generated in //syntax//. @e ExtInadequateVM_SYNERROR @e ExtMisidentifiedEnds_SYNERROR @e UnavailableLOS_SYNERROR +@e DialogueOnSectionsOnly_SYNERROR @ The next tweak to //syntax// is to give it some node metadata. //syntax// itself places nodes of a small number of basic types into the syntax tree; @@ -210,6 +211,8 @@ and here goes: book ... | ==> { 2, - } part ... | ==> { 3, - } chapter ... | ==> { 4, - } + section ... ( dialog ) | ==> { 6, - } + section ... ( dialogue ) | ==> { 6, - } section ... ==> { 5, - } ::= diff --git a/inform7/Tests/Test Problems/PM_DialogueOnSectionsOnly.txt b/inform7/Tests/Test Problems/PM_DialogueOnSectionsOnly.txt new file mode 100644 index 000000000..5e570f8a8 --- /dev/null +++ b/inform7/Tests/Test Problems/PM_DialogueOnSectionsOnly.txt @@ -0,0 +1,5 @@ +Lab is a room. + +Book 1 - Meeting (dialogue) + +Section 1 - Actual Meeting (dialogue) diff --git a/inform7/Tests/Test Problems/PM_UnexpectedDialogue.txt b/inform7/Tests/Test Problems/PM_UnexpectedDialogue.txt new file mode 100644 index 000000000..ab45281d8 --- /dev/null +++ b/inform7/Tests/Test Problems/PM_UnexpectedDialogue.txt @@ -0,0 +1,13 @@ +Lab is a room. + +Section 1 - Meeting (dialogue) + +The claw is here. + +(About the paranormal.) + +Marcellus: "What, has this thing appear'd again to-night?" + +Bernardo: "I have seen naught but [list of things in the Battlements]." + +Marcellus: "Horatio says 'tis but our fantasy." diff --git a/inform7/Tests/Test Problems/_Results_Ideal/PM_DialogueOnSectionsOnly.txt b/inform7/Tests/Test Problems/_Results_Ideal/PM_DialogueOnSectionsOnly.txt new file mode 100644 index 000000000..bc312c758 --- /dev/null +++ b/inform7/Tests/Test Problems/_Results_Ideal/PM_DialogueOnSectionsOnly.txt @@ -0,0 +1,10 @@ +Inform 7 v10.2.0 has started. +I've now read your source text, which is 15 words long. +I've also read Basic Inform by Graham Nelson, which is 7691 words long. +I've also read English Language by Graham Nelson, which is 2328 words long. +I've also read Standard Rules by Graham Nelson, which is 32187 words long. +Problem__ PM_DialogueOnSectionsOnly + >--> In the heading 'Book 1 - Meeting (dialogue)' (source text, line 3), + you've marked for '(dialogue)', but only Sections can be so marked - not + Chapters, Books, and so on. +Inform 7 has finished. diff --git a/inform7/Tests/Test Problems/_Results_Ideal/PM_UnexpectedDialogue.txt b/inform7/Tests/Test Problems/_Results_Ideal/PM_UnexpectedDialogue.txt new file mode 100644 index 000000000..efcb9ecf6 --- /dev/null +++ b/inform7/Tests/Test Problems/_Results_Ideal/PM_UnexpectedDialogue.txt @@ -0,0 +1,11 @@ +Inform 7 v10.2.0 has started. +I've now read your source text, which is 43 words long. +I've also read Basic Inform by Graham Nelson, which is 7691 words long. +I've also read English Language by Graham Nelson, which is 2328 words long. +I've also read Standard Rules by Graham Nelson, which is 32187 words long. +Problem__ PM_UnexpectedDialogue + >--> The text 'The claw is here .' (source text, line 5) appears under a + section heading marked as dialogue, so it needs to be either a cue in + brackets '(like this.)', or else a line of dialogue 'Speaker: "Something to + say!"'. It doesn't seem to be either of those. +Inform 7 has finished. diff --git a/inform7/assertions-module/Chapter 2/Passes through Major Nodes.w b/inform7/assertions-module/Chapter 2/Passes through Major Nodes.w index b5a476160..ce01b87be 100644 --- a/inform7/assertions-module/Chapter 2/Passes through Major Nodes.w +++ b/inform7/assertions-module/Chapter 2/Passes through Major Nodes.w @@ -132,6 +132,9 @@ organisation, and are not directly functional in themselves. #endif break; + case DIALOGUE_CUE_NT: break; /* not yet implemented */ + case DIALOGUE_LINE_NT: break; /* not yet implemented */ + case INVOCATION_LIST_NT: break; /* for error recovery; shouldn't be here otherwise */ case UNKNOWN_NT: break; /* for error recovery; shouldn't be here otherwise */ diff --git a/inform7/core-module/Chapter 1/Core Module.w b/inform7/core-module/Chapter 1/Core Module.w index 6a87c6a98..5016c868b 100644 --- a/inform7/core-module/Chapter 1/Core Module.w +++ b/inform7/core-module/Chapter 1/Core Module.w @@ -20,16 +20,13 @@ to be part of a released version. @e INFORM_INTER_DA = -compiler_feature *core_feature, *naming_feature, *counting_feature, *experimental_feature; +compiler_feature *naming_feature, *counting_feature; void CoreModule::start(void) { - core_feature = Features::new(NULL, I"core", NULL); - Features::make_permanently_active(core_feature); + Features::activate_core(); naming_feature = Features::new(&Naming::start, I"naming", core_feature); counting_feature = Features::new(&InstanceCounting::start, I"instance counting", core_feature); - experimental_feature = Features::new(NULL, I"experimental features", NULL); - Log::declare_aspect(TASK_QUEUE_DA, L"task queue", FALSE, FALSE); Log::declare_aspect(INTER_DA, L"inter", FALSE, FALSE); Log::declare_aspect(INFORM_INTER_DA, L"inform inter", FALSE, FALSE); diff --git a/inform7/core-module/Chapter 2/Problems With Source Text.w b/inform7/core-module/Chapter 2/Problems With Source Text.w index f0638a526..293847958 100644 --- a/inform7/core-module/Chapter 2/Problems With Source Text.w +++ b/inform7/core-module/Chapter 2/Problems With Source Text.w @@ -427,6 +427,25 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) { "for that language does not provide a file of Preform definitions."); Problems::issue_problem_end(); break; + case DialogueOnSectionsOnly_SYNERROR: + current_sentence = CE->details_node; + Problems::quote_source(1, current_sentence); + StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_DialogueOnSectionsOnly)); + Problems::issue_problem_segment( + "In the heading %1, you've marked for '(dialogue)', but only " + "Sections can be so marked - not Chapters, Books, and so on."); + Problems::issue_problem_end(); + break; + case UnexpectedDialogue_SYNERROR: + Problems::quote_source(1, Diagrams::new_UNPARSED_NOUN(CE->details_W)); + StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_UnexpectedDialogue)); + Problems::issue_problem_segment( + "The text %1 appears under a section heading marked as dialogue, " + "so it needs to be either a cue in brackets '(like this.)', or " + "else a line of dialogue 'Speaker: \"Something to say!\"'. It " + "doesn't seem to be either of those."); + Problems::issue_problem_end(); + break; default: internal_error("unknown syntax error"); } diff --git a/services/arch-module/Chapter 3/Feature Manager.w b/services/arch-module/Chapter 3/Feature Manager.w index be966df92..3842b6d78 100644 --- a/services/arch-module/Chapter 3/Feature Manager.w +++ b/services/arch-module/Chapter 3/Feature Manager.w @@ -163,3 +163,16 @@ void Features::run_activation_function(compiler_feature *F) { if (start) (*start)(); } } + +@ Basic features which are present in all three Inform compiler tools: + += +compiler_feature *core_feature = NULL, *experimental_feature = NULL, *dialogue_feature = NULL; + +void Features::activate_core(void) { + core_feature = Features::new(NULL, I"core", NULL); + Features::make_permanently_active(core_feature); + + experimental_feature = Features::new(NULL, I"experimental features", NULL); + dialogue_feature = Features::new(NULL, I"dialogue", experimental_feature); +} diff --git a/services/linguistics-test/Tests/Test Diagrams/_Results_Ideal/recursive-bad-trace.txt b/services/linguistics-test/Tests/Test Diagrams/_Results_Ideal/recursive-bad-trace.txt index 0bf150841..94cf1968c 100644 --- a/services/linguistics-test/Tests/Test Diagrams/_Results_Ideal/recursive-bad-trace.txt +++ b/services/linguistics-test/Tests/Test Diagrams/_Results_Ideal/recursive-bad-trace.txt @@ -1,6 +1,6 @@ Seek verb in: there is a ming vase on the table called the table of having viability map of 'there is a ming vase on the table called the table of having': - -- is[1] -- -- -- -- -- -- -- -- -- of[1] -- + -- is[1] -- -- -- -- -- -- called[1] -- -- -- -- Found usage, pass 1 tier 2: (there) be(0) (a ming vase on the table called the table of having) Seek verb in: a ming vase on the table | called the table of having viability map of 'a ming vase on the table called the table of having': diff --git a/services/syntax-module/Chapter 2/Node Types.w b/services/syntax-module/Chapter 2/Node Types.w index ec504920e..d28aa1358 100644 --- a/services/syntax-module/Chapter 2/Node Types.w +++ b/services/syntax-module/Chapter 2/Node Types.w @@ -212,20 +212,24 @@ do this. All a bit clumsy, but it works. @e SENTENCE_NT /* "The Garden is a room" */ @e AMBIGUITY_NT /* Marks an ambiguous set of readings in the tree */ @e UNKNOWN_NT /* "arfle barfle gloop" */ +@e DIALOGUE_CUE_NT /* A dialogue cue under a dialogue Section heading */ +@e DIALOGUE_LINE_NT /* A line of dialogue under a dialogue Section heading */ = void NodeType::metadata_setup(void) { - NodeType::new(INVALID_NT, I"(INVALID_NT)", 0, INFTY, INVALID_NCAT, 0); + NodeType::new(INVALID_NT, I"(INVALID_NT)", 0, INFTY, INVALID_NCAT, 0); - NodeType::new(ROOT_NT, I"ROOT_NT", 0, INFTY, L1_NCAT, DONT_VISIT_NFLAG); - NodeType::new(INCLUSION_NT, I"INCLUSION_NT", 0, INFTY, L1_NCAT, DONT_VISIT_NFLAG); - NodeType::new(HEADING_NT, I"HEADING_NT", 0, INFTY, L1_NCAT, 0); - NodeType::new(INCLUDE_NT, I"INCLUDE_NT", 0, 0, L2_NCAT, 0); - NodeType::new(BEGINHERE_NT, I"BEGINHERE_NT", 0, 0, L2_NCAT, 0); - NodeType::new(ENDHERE_NT, I"ENDHERE_NT", 0, 0, L2_NCAT, 0); - NodeType::new(SENTENCE_NT, I"SENTENCE_NT", 0, INFTY, L2_NCAT, 0); - NodeType::new(AMBIGUITY_NT, I"AMBIGUITY_NT", 0, INFTY, L1_NCAT, 0); - NodeType::new(UNKNOWN_NT, I"UNKNOWN_NT", 0, INFTY, UNKNOWN_NCAT, 0); + NodeType::new(ROOT_NT, I"ROOT_NT", 0, INFTY, L1_NCAT, DONT_VISIT_NFLAG); + NodeType::new(INCLUSION_NT, I"INCLUSION_NT", 0, INFTY, L1_NCAT, DONT_VISIT_NFLAG); + NodeType::new(HEADING_NT, I"HEADING_NT", 0, INFTY, L1_NCAT, 0); + NodeType::new(INCLUDE_NT, I"INCLUDE_NT", 0, 0, L2_NCAT, 0); + NodeType::new(BEGINHERE_NT, I"BEGINHERE_NT", 0, 0, L2_NCAT, 0); + NodeType::new(ENDHERE_NT, I"ENDHERE_NT", 0, 0, L2_NCAT, 0); + NodeType::new(SENTENCE_NT, I"SENTENCE_NT", 0, INFTY, L2_NCAT, 0); + NodeType::new(AMBIGUITY_NT, I"AMBIGUITY_NT", 0, INFTY, L1_NCAT, 0); + NodeType::new(UNKNOWN_NT, I"UNKNOWN_NT", 0, INFTY, UNKNOWN_NCAT, 0); + NodeType::new(DIALOGUE_CUE_NT, I"DIALOGUE_CUE_NT", 0, INFTY, L2_NCAT, 0); + NodeType::new(DIALOGUE_LINE_NT, I"DIALOGUE_LINE_NT", 0, INFTY, L2_NCAT, 0); #ifdef NODE_METADATA_SETUP_SYNTAX_CALLBACK NODE_METADATA_SETUP_SYNTAX_CALLBACK(); diff --git a/services/syntax-module/Chapter 3/Sentences.w b/services/syntax-module/Chapter 3/Sentences.w index 024b3f81d..8df6738b7 100644 --- a/services/syntax-module/Chapter 3/Sentences.w +++ b/services/syntax-module/Chapter 3/Sentences.w @@ -48,6 +48,7 @@ typedef struct syntax_fsm_state { node_type_t nt; int inside_rule_mode; int inside_table_mode; + int inside_dialogue_mode; PROBLEM_REF_SYNTAX_TYPE *ref; PROJECT_REF_SYNTAX_TYPE *project_ref; } syntax_fsm_state; @@ -69,6 +70,8 @@ void Sentences::reset(syntax_fsm_state *sfsm, int is_extension, PROBLEM_REF_SYNTAX_TYPE *ref, PROJECT_REF_SYNTAX_TYPE *project_ref) { sfsm->sf = NULL; sfsm->inside_rule_mode = FALSE; + sfsm->inside_table_mode = FALSE; + sfsm->inside_dialogue_mode = FALSE; sfsm->skipping_material_at_level = -1; sfsm->ref = ref; sfsm->project_ref = project_ref; @@ -89,6 +92,7 @@ void Sentences::reset(syntax_fsm_state *sfsm, int is_extension, @e ExtNoEndsHere_SYNERROR @e HeadingOverLine_SYNERROR @e HeadingStopsBeforeEndOfLine_SYNERROR +@e UnexpectedDialogue_SYNERROR @ Now for the function itself. We break into bite-sized chunks, each of which is despatched to the |Sentences::make_node| function with a note of the punctuation @@ -208,19 +212,22 @@ sentence divisions. The other cases are more complicated: see below. if (stop_character == ':') @; stop_character = '|'; stopped = TRUE; } - if (Lexer::word(at) == FULLSTOP_V) { - if (stop_character == ':') @; - if (stop_character == ';') @; - stop_character = '.'; stopped = TRUE; - } - if (Lexer::word(at) == SEMICOLON_V) { - if (stop_character == ':') @; - if (stop_character == '.') @; - stop_character = ';'; stopped = TRUE; - } + + if (sfsm->inside_dialogue_mode == FALSE) { + if (Lexer::word(at) == FULLSTOP_V) { + if (stop_character == ':') @; + if (stop_character == ';') @; + stop_character = '.'; stopped = TRUE; + } + if (Lexer::word(at) == SEMICOLON_V) { + if (stop_character == ':') @; + if (stop_character == '.') @; + stop_character = ';'; stopped = TRUE; + } - @; - @; + @; + @; + } if (stopped == FALSE) break; no_stop_words++; at++; @@ -325,7 +332,7 @@ or until reaching the end of the text: whichever comes first. = void Sentences::make_node(parse_node_tree *T, wording W, int stop_character) { - int heading_level = 0; + int heading_level = 0, entering_dialogue = FALSE; int begins_or_ends = 0; /* 1 for "begins here", -1 for "ends here" */ parse_node *new; @@ -343,6 +350,7 @@ void Sentences::make_node(parse_node_tree *T, wording W, int stop_character) { if (sfsm->skipping_material_at_level >= 0) return; if (heading_level > 0) { + sfsm->inside_dialogue_mode = entering_dialogue; @; @; @; @@ -386,7 +394,15 @@ important), or |-1| to mean that the sentence begins an extension, or switch (<>) { case -1: if (sfsm->ext_pos != NO_EXTENSION_POS) begins_or_ends = 1; break; case -2: if (sfsm->ext_pos != NO_EXTENSION_POS) begins_or_ends = -1; break; - default: heading_level = <>; break; + default: + if (<> == 6) { + heading_level = 5; + entering_dialogue = TRUE; + } else { + heading_level = <>; + entering_dialogue = FALSE; + } + break; } } @@ -492,6 +508,7 @@ sentences and options-file sentences may have been read already.) } @ = + if (sfsm->inside_dialogue_mode) @; @; @; @@ -523,6 +540,35 @@ sentences and options-file sentences may have been read already.) NEW_NONSTRUCTURAL_SENTENCE_SYNTAX_CALLBACK(new); #endif +@ + += + ::= + ( ... ) | ==> { 1, - } + ...... : ...... ==> { 2, - } + +@ = + if ((W)) { + switch (<>) { + case 1: + new = Node::new(DIALOGUE_CUE_NT); + Node::set_text(new, W); + SyntaxTree::graft_sentence(T, new); + return; + case 2: + new = Node::new(DIALOGUE_LINE_NT); + Node::set_text(new, W); + SyntaxTree::graft_sentence(T, new); + return; + } + } else { + Sentences::syntax_problem(UnexpectedDialogue_SYNERROR, W, sfsm->ref, 0); + new = Node::new(UNKNOWN_NT); + Node::set_text(new, W); + SyntaxTree::graft_sentence(T, new); + } + return; + @ We make an exception to the exception for the serial comma used in a list of alternatives: thus the comma in "Aeschylus, Sophocles, or Euripides" does not trigger this rule. We need this exception because such lists of diff --git a/services/syntax-test/Chapter 1/Program Control.w b/services/syntax-test/Chapter 1/Program Control.w index 4358f9eef..56d644c17 100644 --- a/services/syntax-test/Chapter 1/Program Control.w +++ b/services/syntax-test/Chapter 1/Program Control.w @@ -7,6 +7,7 @@ What shall we test? @d PROGRAM_NAME "syntax-test" @e TEST_TREE_CLSW +@e TEST_DIALOGUE_CLSW = int main(int argc, char **argv) { @@ -18,6 +19,8 @@ int main(int argc, char **argv) { CommandLine::declare_switch(TEST_TREE_CLSW, L"test-tree", 2, L"test the syntax tree (from text in X)"); + CommandLine::declare_switch(TEST_DIALOGUE_CLSW, L"test-dialogue", 2, + L"test a syntax tree with dialogue (from text in X)"); CommandLine::read(argc, argv, NULL, &Main::respond, &Main::ignore); @@ -30,6 +33,7 @@ int main(int argc, char **argv) { void Main::respond(int id, int val, text_stream *arg, void *state) { switch (id) { case TEST_TREE_CLSW: Main::load(I"Syntax.preform"); Unit::test_tree(arg); break; + case TEST_DIALOGUE_CLSW: Main::load(I"Syntax.preform"); Unit::test_tree(arg); break; } } diff --git a/services/syntax-test/Chapter 1/Unit Tests.w b/services/syntax-test/Chapter 1/Unit Tests.w index 93f226035..0d1331126 100644 --- a/services/syntax-test/Chapter 1/Unit Tests.w +++ b/services/syntax-test/Chapter 1/Unit Tests.w @@ -8,8 +8,13 @@ any text but then fail. = ::= - chapter ... | ==> { 1, - } - section ... ==> { 2, - } + volume ... | ==> { 1, - } + book ... | ==> { 2, - } + part ... | ==> { 3, - } + chapter ... | ==> { 4, - } + section ... ( dialog ) | ==> { 6, - } + section ... ( dialogue ) | ==> { 6, - } + section ... ==> { 5, - } ::= ... ==> { fail } diff --git a/services/syntax-test/Tests/Test Cases/_Results_Ideal/dialogue.txt b/services/syntax-test/Tests/Test Cases/_Results_Ideal/dialogue.txt new file mode 100644 index 000000000..4976563bb --- /dev/null +++ b/services/syntax-test/Tests/Test Cases/_Results_Ideal/dialogue.txt @@ -0,0 +1,9 @@ +Read 38 words +ROOT_NT + HEADING_NT'elsinore is a room' {heading 0} + SENTENCE_NT'elsinore is a room' + HEADING_NT'section 1 - on the battlements ( dialogue )' {heading 5} + DIALOGUE_CUE_NT'( about the paranormal . )' + DIALOGUE_LINE_NT'marcellus : "What, has this thing appear'd again to-night?"' + DIALOGUE_LINE_NT'bernardo : "I have seen naught but [list of things in the Ba' + DIALOGUE_LINE_NT'marcellus : "Horatio says 'tis but our fantasy."' diff --git a/services/syntax-test/Tests/Test Cases/_Results_Ideal/tree.txt b/services/syntax-test/Tests/Test Cases/_Results_Ideal/tree.txt index 7e0f74f55..a1b0235ce 100644 --- a/services/syntax-test/Tests/Test Cases/_Results_Ideal/tree.txt +++ b/services/syntax-test/Tests/Test Cases/_Results_Ideal/tree.txt @@ -1,10 +1,10 @@ Read 106 words ROOT_NT HEADING_NT'chapter 1' {heading 0} - HEADING_NT'chapter 1' {heading 1} + HEADING_NT'chapter 1' {heading 4} SENTENCE_NT'i burn to paint a certain woman who has appeared to me so ra' SENTENCE_NT'it is already long since i saw her' SENTENCE_NT'she is beautiful , and more than beautiful , she is overpowe' - HEADING_NT'chapter 2' {heading 1} + HEADING_NT'chapter 2' {heading 4} SENTENCE_NT'i would compare her to a black sun if one could conceive of ' SENTENCE_NT'but it is the moon that she makes one dream of most readily' diff --git a/services/syntax-test/Tests/Test Cases/dialogue.txt b/services/syntax-test/Tests/Test Cases/dialogue.txt new file mode 100644 index 000000000..f0d6a4b86 --- /dev/null +++ b/services/syntax-test/Tests/Test Cases/dialogue.txt @@ -0,0 +1,11 @@ +Elsinore is a room. + +Section 1 - On the Battlements (dialogue) + +(About the paranormal.) + +Marcellus: "What, has this thing appear'd again to-night?" + +Bernardo: "I have seen naught but [list of things in the Battlements]." + +Marcellus: "Horatio says 'tis but our fantasy."