Advertisement
ZoriaRPG

ZScript Beam Parser v0.2

Jan 22nd, 2017
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.84 KB | None | 0 0
  1. /* Beam=Style TBA Text Parser
  2.    I hope to support the full Beam 'Inglish' with this, eventually, but
  3.    if not, it should be a modest text parser tor TBA style quests, or even
  4.    normal quests where the developer can read strings to find command keywords and
  5.    act on them.
  6.  
  7.    At present, there is a five WORD stack, and a heap that can support caching
  8.    commands, offsetting them, and acting on them later.
  9.  
  10.    This is not fully-considered, as Beam's 'Inglish' parser supported conjunctions
  11.    and prepositions. Adding those, or at least the logic for those will require a
  12.    larger stack, and some unconventional memory management.
  13.    
  14.    Beam's maximum parse string length was 128-characters.
  15. */
  16.  
  17. int instructions[214747];
  18. int command[18];
  19.  
  20.  
  21. int tempbuffer[55];
  22. int outputbuffers[10];
  23.  
  24. void OutputText(int bufferID, int outoutID){
  25.     //copy text from input to output
  26. }
  27.  
  28. void GameText(){
  29.     //string processor
  30.  
  31. }
  32.  
  33. int stack[5]; //holds the four possible command components
  34. int heap[32]; //May not need it, but it might be good for something.
  35. int ADJ_NOUN[36]; //buffer for a combined adjective and noun pairing.
  36.     //Used to compare the names of screen items, and enemies.
  37.     //36 chars = 17+17+space+NULL Probably too long for any pair, but that is a minor waste.
  38.  
  39. //Perhaps a SAY string?
  40.  
  41. //ASM TYPES
  42. #define ACTION 1;
  43. #define NOUN 2;
  44. #define ADJECTIVE 3;
  45. #define INVALID -1;
  46.  
  47. /*  Do we want to allow constructing very complex chains, such as OLD KEY as two
  48.     compinents, or do we want to hardcode OLD KEY or HIDEOUS TROLL as one string?
  49.  
  50.     Clearly, the latter is easier.
  51. */
  52.  
  53. //ASM DEFINE
  54. #define NORTH 1;
  55. #define EAST 2;
  56. #define WEST 3;
  57. #define SOUTH 4;
  58. #define UP 5;
  59. #define DOWN 6;
  60. #define LOOK 7;
  61. #define TAKE 8;
  62. #define WAIT 9;
  63. #define ASK 10;
  64. #define SAY 11;
  65. #define ATTACK 12;
  66. #define USE 13;
  67. #define EQUIP 14;
  68. #define GIVE 15;
  69.  
  70. int matchaction(int command){
  71.    
  72.    
  73. }
  74.  
  75. //Returns how many total WORDS are in one instruction set.
  76. int numinstructions(int _buffer){
  77.     ///count the number of spaces in the buffer. THe number of total instructions
  78.     ///equals the number  of spaces, plus onwe
  79.     int spc; int nextchar; bool trailspacedone;
  80.     INSTRUCTIONS_SIZE = SizeOfArray(_buffer);
  81.     for ( int q = SizeOfArray(_buffer); q >= 0; q-- ) {
  82.         //don't count trailing spaces, or contiguous spaces.
  83.         if ( _buffer[q] == CHAR_SPACE ) {
  84.             if ( __buffer[q-1] !isLetter() && !trailspacedone ) {
  85.                 trailspacedone = false; continue;
  86.             }
  87.             else if ( __buffer[q-1] isLetter() && !trailspacedone ) {
  88.                 trailspacedone = true;
  89.                 spc++; continue;
  90.             }
  91.             else if ( __buffer[q-1] !isLetter() && trailspacedone ) continue;
  92.             else if ( __buffer[q-1] isLetter() && trailspacedone ) {
  93.                 spc++;
  94.             }
  95.         }
  96.     }
  97.     //WORDCOUNT[0] = spc+1; //store the total number of words.
  98.     return spc+1;
  99. }
  100.  
  101. //int WORDS[4];
  102. //holds the indices of each word?
  103.  
  104. #define MAX_WORDS 5; //Max words per instruction. SAY GANDALF GIVE OLD KEY
  105. //Store each word in these buffers.
  106. int WORD_1[18];
  107. int WORD_2[18];
  108. int WORD_3[18];
  109. int WORD_4[18];
  110. int WORD_5[18];
  111. int WordCount; //how many words this time, and the index at which they occur.
  112. int INSTRUCTIONS_SIZE; //Used by functions to minimise loop wastage.
  113.  
  114. //Stores the present commands in the text parsing buffer into command slots.
  115. void GetInstructions(int _buffer){
  116.     int wordcount = numinstructions(_buffer);
  117.     int WORDS[5]={WORD_1, WORD_2, WORD_3, WORD4, WORD_5}; //holds the array pointers.
  118.     //This time, read the array forward.
  119.     int spc; int nextchar; bool trailspacedone; int curword = 0;
  120.    
  121.     for ( int q = 0; q < INSTRUCTIONS_SIZE; q++ ) {
  122.         //don't count trailing spaces, or contiguous spaces.
  123.         if ( curword < wordcount ) {
  124.             do {
  125.                 int ptr = WORDS[curword];
  126.                 ptr[q] = _buffer[q];
  127.             }
  128.             while ( _buffer[q] != CHAR_SPACE && spc < wordcount );
  129.             curword++;
  130.         }
  131.     }
  132.        
  133. }
  134.  
  135.  
  136. //Add instructions to the 'stack', starting with a COMMAND, then its variables.
  137. void StringToCommand(){
  138.     int buf[3] = "0"; int  buf2[2];
  139.     //one string per command
  140.    
  141.     //command lengths
  142.     //this speeds up matching the string to a command by finding one of the same length
  143.     int commandlengths[]={5, 4, 4, 5, 2, 4, 4, 4, 4, 4, 3, 3, 6, 3}; //list the length of each command in order.
  144.     //match the
  145.    
  146.     int legalcommands[]="
  147.         01NORTH
  148.         2EAST
  149.         3WEST
  150.         4SOUTH
  151.         5UP
  152.         6DOWN
  153.         7LOOK
  154.         8TAKE
  155.         9WAIT
  156.         10ASK
  157.         11SAY
  158.         12ATTACK
  159.         13USE
  160.     ";
  161.     //We then check the length of the command
  162.    
  163.     /* We probably don't need a switch for this. Just do:
  164.     */
  165.    
  166.     //Do we want a switch for this?
  167.     //switch (INSTRUCTIONS_SIZE){
  168.     //  case 1:
  169.             //COMMAND only, no verb, no say.
  170.    
  171.     //Parse WORD_1
  172.    
  173.     int curWord = 0;
  174.     int WORDS[5]={WORD_1, WORD_2, WORD_3, WORD4, WORD_5}; //holds the array pointers.
  175.    
  176.     //First, the command
  177.     strcpy(WORDS[curWord], temp_command); //store the present word
  178.    
  179.     for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  180.         bool match;
  181.         if ( commandlengths[q] == strlen(temp_command) {
  182.             //if the position of q is < 10, append a leading 0
  183.             if ( q < 10 ) {
  184.                 itoa(q,buf2);
  185.                 strcat(buf2, but);
  186.             }
  187.             //otherwise, just store it
  188.             itoa(q, buf); //overwrite the temp buffer.
  189.            
  190.             //find that number in legal commands
  191.             for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  192.                
  193.                 //! stringparser finds a matching string, and returns its position?
  194.                    
  195.                 //if ( stringparser(buf) ) return q; //if the string matches
  196.                
  197.                 //This is the inverse of the old string parser, so instead, let's do this
  198.                
  199.                 int bufcompare[18];
  200.                 stringparser(q, bufcompare); //copy instruction q into the compare buffer
  201.                 for ( int e = 0; e < strlen(bufcompare); e++ ) {
  202.                     //compare each index
  203.                     if ( temp_command[e] != bufcompare[3] ) {
  204.                         //failed to compare
  205.                         match = false;
  206.                         break;
  207.                     }
  208.                     match = true; //we found the match.
  209.                     //return atoi(buf); //return the command ID.
  210.                    
  211.                    
  212.                    
  213.                     //! no, we want to store the commcomamnd, to parse,
  214.                     //! and add variables to it.
  215.                     stack[curWord] = atoi(buf);
  216.                     break;
  217.                 }
  218.                
  219.                 //the parsed string, thast is its command number.
  220.                 //so, return it.
  221.                  
  222.             }
  223.             break; //if we fail, we fall through.
  224.         }
  225.         if ( !match ) stack[curWord] = INVALID; //return INVALID; //invalid command
  226.         //!! no, put INVALID into the stack.
  227.     }
  228.     curWord++; //Increase the SP.
  229.    
  230.     int legal_variables="
  231.    
  232.    
  233.    
  234.    
  235.    
  236.     ";
  237.    
  238.     //Then, its VARIABLES, if any.
  239.     for ( int q = 1; q < WordCount; q++ ) {
  240.         strcpy(WORDS[curWord], temp_command); //store the present word
  241.    
  242.         for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  243.             bool match;
  244.             if ( commandlengths[q] == strlen(temp_command) {
  245.                 //if the position of q is < 10, append a leading 0
  246.                 if ( q < 10 ) {
  247.                     itoa(q,buf2);
  248.                     strcat(buf2, but);
  249.                 }
  250.                 //otherwise, just store it
  251.                 itoa(q, buf); //overwrite the temp buffer.
  252.                
  253.                 //find that number in legal commands
  254.                 for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  255.                    
  256.                     //! stringparser finds a matching string, and returns its position?
  257.                        
  258.                     //if ( stringparser(buf) ) return q; //if the string matches
  259.                    
  260.                     //This is the inverse of the old string parser, so instead, let's do this
  261.                    
  262.                     int bufcompare[18];
  263.                     stringparser(q, bufcompare); //copy instruction q into the compare buffer
  264.                     for ( int e = 0; e < strlen(bufcompare); e++ ) {
  265.                         //compare each index
  266.                         if ( temp_command[e] != bufcompare[3] ) {
  267.                             //failed to compare
  268.                             match = false;
  269.                             break;
  270.                         }
  271.                         match = true; //we found the match.
  272.                         //return atoi(buf); //return the command ID.
  273.                        
  274.                        
  275.                        
  276.                         //! no, we want to store the commcomamnd, to parse,
  277.                         //! and add variables to it.
  278.                         stack[curWord] = atoi(buf);
  279.                         break;
  280.                     }
  281.                    
  282.                     //the parsed string, thast is its command number.
  283.                     //so, return it.
  284.                      
  285.                 }
  286.                 break; //if we fail, we fall through.
  287.             }
  288.             if ( !match ) stack[curWord] = INVALID; //return INVALID; //invalid command
  289.             //!! no, put INVALID into the stack.
  290.         }
  291.         currWord++; //Increase the SP.
  292.     }
  293. }
  294.        
  295.    
  296. void doaction(int action){
  297.     //get actions off the stack, and pop them
  298.     int tempheap[5]; int command;
  299.     for ( int q = 0; q <= MAX_WORDS; q++ ){
  300.         hempheap[q] = stack[q];
  301.         stack[q] = 0; //popped
  302.     }
  303.    
  304.     switch(NUMWORDS){
  305.         case 1:
  306.            
  307.             //actions only
  308.             command = tempheap[0];
  309.            
  310.             switch(command){
  311.                
  312.                
  313.                
  314.             }
  315.    
  316.        
  317.         case 2:
  318.            
  319.             //action and noun
  320.             int command = tempstack[0];
  321.             int adjective = tempstack[1];
  322.             int noun = tempstack[2];
  323.        
  324.             switch(noun){
  325.                 //find the object by checking for NOUN on screen
  326.                 case 1:
  327.                     switch(command){
  328.                        
  329.                         case 1:
  330.                             //perform action on noun
  331.                     }
  332.                 }
  333.             }
  334.        
  335.         case 3: //command, and two words
  336.             //can be 'command adjective noun'
  337.             int command = tempstack[0];
  338.             int adjective = tempstack[1];
  339.             int noun = tempstack[2];
  340.             //append adjective to ADJECTIVE_NOUN[36]
  341.                         //and append a space
  342.                             //append the noun to the ADCECTIVE_NOUN string
  343.             switch(noun){
  344.                
  345.                 //!!!!!!!
  346.                 //! it might improve performance to do the adjective and noun first, and perform the command
  347.                 //case, on those.
  348.                
  349.                
  350.                     //determine of the noun is an enemy, or an item.
  351.                 case 1:
  352.                 case 2:
  353.                 case 3: //items
  354.                     //item cases go here
  355.                     //check for items matchint the ADJECTIVE_NOUN string by name
  356.                     //if they exist, perform the action on them, if possible
  357.                
  358.                     //if they are not on screen, but are in inventory, perform the action.
  359.                 switch(action){
  360.                     case TAKE:
  361.                         break;
  362.                     case GIVE;
  363.                         break;
  364.                     case USE:
  365.                         break;
  366.                     case EQUIP:
  367.                         break;
  368.                     default:
  369.                         SyntaxErr();
  370.                         break;
  371.                    
  372.                     //Perform the action on the target.
  373.                 }
  374.                 break;
  375.                
  376.                 //enemies
  377.                 case TROLL:
  378.                 case GOBLIN:
  379.                 case GOLLUM:
  380.                 case SMAUG:
  381.                     switch(action){
  382.                         case ATTACK:
  383.                             break;
  384.                         default:
  385.                             SyntaxErr();
  386.                             break;
  387.                     //Perform the action on the target.
  388.                 }
  389.                 break;
  390.                     //Scan the screen for an npc that matches the string ADJECTIVE_NOUN
  391.                    
  392.                 case OTHER:
  393.                     SyntaxErr();
  394.                     break;
  395.                 /*
  396.                 switch(adjective){
  397.                     //narrow the field? Do we ever need to do this?
  398.                    
  399.                     case 1:
  400.                         int noun = tempstack[2];
  401.                         //append adjective to ADJECTIVE_NOUN[36]
  402.                         //and append a space
  403.                         switch(noun){
  404.                             //append the noun to the ADCECTIVE_NOUN string
  405.                             case 1:
  406.                                 //item cases go here
  407.                                 //check for items matchint the ADJECTIVE_NOUN string by name
  408.                                 //if they exist, perform the action on them, if possible
  409.                            
  410.                                 //if they are not on screen, but are in inventory, perform the action.
  411.                         }
  412.                 }
  413.                
  414.                 switch(action){
  415.                    
  416.                     Perform the action on the target.
  417.                 }
  418.                 */
  419.                 default:
  420.                     SyntaxErr();
  421.                     break;
  422.                
  423.                
  424.             }
  425.            
  426.         case 4: //command and three words
  427.             /* this is where things become quite complex, as this includes the SAY
  428.                 instruction. In fact... I believe that 4 must alays be the say instruction.
  429.                 //! Don;t forget 'CARRY'
  430.             */
  431.             int person = tempstack[1];
  432.             int action = tempstack[2];
  433.             int noun = tempstack[3];
  434.        
  435.             switch (command){
  436.                 case SAY:
  437.                     //if the command isn't say, then we're doing something else, likely syntax err.,
  438.                     case (person){
  439.                         //check to see if the person is present.
  440.                         case GANDALF:
  441.                             if ( !isGandalfPresent() ) break;
  442.                         case THORIN:
  443.                             if ( !isThorinPresent() ) break;
  444.                         case ELROND:
  445.                             if ( !isElrondPresent() ) break;
  446.                         case GOLLUM
  447.                             if ( !isTHorinPresent() ) break;
  448.                         case BEORN:
  449.                             if ( !isBeornPresent() ) break;
  450.                         case BARD:
  451.                             if ( !isTHorinPresent() ) break;
  452.                         case SMAUG
  453.                             if ( !isTHorinPresent() ) break;
  454.                        
  455.                             //Each character gets this block, with legal actions and such.
  456.                             switch(action){
  457.                                
  458.                                 case GIVE:
  459.                                     switch(noun){
  460.                                         case 1:
  461.                                             //check objects in inventory
  462.                                             //if we give the object to a character, mark their inventory
  463.                                             //array and remove the object from our own
  464.                                            
  465.                                     }
  466.                                 case ATTACK;
  467.                                     switch(noun){
  468.                                         //check the screen for some creature that matches
  469.                                         //noun by name.
  470.                                         case 1:
  471.                                     }
  472.                             }
  473.                     }
  474.                 default:
  475.                     //not the say command, return an error.
  476.             }
  477.            
  478.         case 5:
  479.             //say, person, action, adjective, noun
  480.         //! Don;t forget 'CARRY'
  481.         switch (command){
  482.                 case SAY:
  483.                     int person = tempstack[1];
  484.                     case (person){
  485.                         case 1:
  486.                             int action = tempstack[2];
  487.                             switch(action){
  488.                                 int adj = tempstack[3];
  489.                                 case 1:
  490.                                     switch(adj){
  491.                                         int noun = tempstack[4];
  492.                                        
  493.                                         case 1:
  494.                                             switch(noun){
  495.                                                 case 1:
  496.                                             }
  497.                                            
  498.                                     }
  499.                             }
  500.                     }
  501.                 default:
  502.                     //not the say command, return an error.
  503.             }
  504.            
  505.     switch(action){
  506.        
  507.         case :
  508.            
  509.         default:
  510.             break;
  511.     }
  512. }
  513.  
  514. //ASM VARIABLES
  515.  
  516. //NOUNS
  517. //Items
  518. #define KEY 1;
  519. #define MAP 2;
  520. #define GOLD 3;
  521. #define SWORD 4;
  522. #define TORCH 5;
  523. #define DAGGER 6;
  524. #define ME 7;
  525.  
  526. //NPCs (person)
  527. #define GANDALF 1;
  528. #define THORIN 2;
  529. #define BARD 3;
  530. #define BEORN 4;
  531. #define ELROND 5;
  532.  
  533. //Enemies
  534. #define TROLL 1;
  535. #define GOBLIN 2;
  536. #define GOLLUM 3;
  537. #define SMAUG 4;
  538.  
  539. //ADJECTIVES
  540. #define STRANGE 1;
  541. #define OLD 2;
  542. #define UNUSUAL 3;
  543. #define GOLDEN 4;
  544. #define UGLY 5;
  545. #define MAGICAL 6;
  546. #define HIDEOUS 7;
  547. #define SHINY 8;
  548.  
  549.  
  550. //Parse types, based on number of commands issued
  551. #define COMMAND 1;
  552. #define VERB 2;
  553. #define NOUN 3;
  554. #define SPEAK 4;
  555.  
  556. //Constructs
  557. //ACTION
  558. //ACTION NOUN
  559. //ACTION VERB NOUN
  560. //SAY NPC SPEAK
  561.  
  562. /*
  563.  
  564.  
  565. GAME DICTIONARY
  566.  
  567. Movements:
  568. DOWN D, EAST E, NORTH N, NORTHEAST NE, NORTHWEST NW, SOUTH S,
  569. SOUTHEAST SE, SOUTHWEST SW, UP U, WEST W.
  570.  
  571. Special verbs:
  572. EXAMINE, HELP, INVENTORY I, LOAD, LOOK L, NOPRINT, PAUSE, PRINT,
  573. QUIT, SAVE, SCORE.
  574. DICTIONARY
  575.  
  576. Action verbs:
  577. BREAK, CLIMB, CLOSE, CROSS, DIG, DROP, DRINK, EMPTY, ENTER, EAT,
  578. FILL, FOLLOW, GIVE, GO, KILL, LOCK, PICK, PUT, OPEN, RUN, SAY,
  579. SHOOT, SWIM, TIE, TAKE, THROW, TURN, UNLOCK, UNTIE, WEAR.
  580.  
  581. Prepositions:
  582. ACROSS, AT, FROM, IN, INTO, ON, OUT, OFF, THROUGH, TO, UP, WITH
  583.  
  584. Adverbs:
  585. CAREFULLY, GENTLY, QUICKLY, SOFTLY, VICIOUSLY
  586.  
  587. */
  588.  
  589. //SPEAK
  590. //ONE WORD
  591.  
  592. //TWO WORDS
  593. //"GIVE" item
  594.     //item NOUN
  595.     //item VERB NOUN
  596. //"CARRY" item, person
  597.     //item NOUN, person
  598.     //item VERB NOUN, person
  599. //"ATTACK"  npc
  600.     //attack, NPC
  601.     //attack VERB NPC
  602.  
  603.  
  604.  
  605. bool Parse(int inputBuffer){
  606.     int
  607.    
  608.    
  609.    
  610. /*
  611.     switch (strlen(temp_command)){
  612.         int buf[3] = "0"; int  buf2[2];
  613.        
  614.         case 3:
  615.            
  616.             //check commands with a length of 3...
  617.             for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  618.                 if ( commandlengths[q] == 3 ) {
  619.                     //if the position of q is < 10, append a leading 0
  620.                     if ( q < 10 ) {
  621.                         itoa(q,buf2);
  622.                         strcat(buf2, but);
  623.                     }
  624.                     //otherwise, just store it
  625.                     itoa(q, buf); //overwrite the temp buffer.
  626.                    
  627.                     //find that number in legal commands
  628.                     for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  629.                         if ( stringparser(buf) ) return q; //if the string matches
  630.                             //the parsed string, thast is its command number.
  631.                         //so, return it.
  632.                     }
  633.                     break; //if we fail, we fall through.
  634.                 }
  635.                 break; //fall though
  636.             }
  637.         case 4:
  638.             //check commands with a length of 3.
  639.             for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  640.                 if ( commandlengths[q] == 4 ) {
  641.                     //if the position of q is < 10, append a leading 0
  642.                     if ( q < 10 ) {
  643.                         itoa(q,buf2);
  644.                         strcat(buf2, but);
  645.                     }
  646.                     //otherwise, just store it
  647.                     itoa(q, buf); //overwrite the temp buffer.
  648.                    
  649.                     //find that number in legal commands
  650.                     for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  651.                         if ( stringparser(buf) ) return q; //if the string matches
  652.                             //the parsed string, thast is its command number.
  653.                         //so, return it.
  654.                     }
  655.                     break; //if we fail, we fall through.
  656.                 }
  657.                 break; //fall though
  658.             }
  659.            
  660.         case 5:
  661.             //check commands with a length of 3.
  662.             for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
  663.                 if ( commandlengths[q] == 4 ) {
  664.                     //if the position of q is < 10, append a leading 0
  665.                     if ( q < 10 ) {
  666.                         itoa(q,buf2);
  667.                         strcat(buf2, but);
  668.                     }
  669.                     //otherwise, just store it
  670.                     itoa(q, buf); //overwrite the temp buffer.
  671.                    
  672.                     //find that number in legal commands
  673.                     for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
  674.                         if ( stringparser(buf) ) return q; //if the string matches
  675.                             //the parsed string, thast is its command number.
  676.                         //so, return it.
  677.                     }
  678.                     break; //if we fail, we fall through.
  679.                 }
  680.                 break; //fall though
  681.             }
  682.            
  683.         case 6:
  684.            
  685.         default:
  686.             //invalid command.
  687.     }
  688.     */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement