180 |
%parse-param {void* yyparse_param} |
%parse-param {void* yyparse_param} |
181 |
|
|
182 |
// After entering the yyparse() function, store references to the parser's |
// After entering the yyparse() function, store references to the parser's |
183 |
// state stack, so that we can create more helpful syntax error messages than |
// symbol stack, so that we can create more helpful syntax error messages than |
184 |
// Bison (2.x) could do. |
// Bison (2.x) could do. |
185 |
%initial-action { |
%initial-action { |
186 |
yyparse_param_t* p = (yyparse_param_t*) yyparse_param; |
yyparse_param_t* p = (yyparse_param_t*) yyparse_param; |
1457 |
* precise parse position & state represented by @a stack, according to Bison's |
* precise parse position & state represented by @a stack, according to Bison's |
1458 |
* LALR(1) parser algorithm. |
* LALR(1) parser algorithm. |
1459 |
* |
* |
1460 |
* This function is given a Bison parser state stack, reflecting the parser's |
* This function is given a Bison parser symbol stack, reflecting the parser's |
1461 |
* entire state at a certain point, i.e. when a syntax error occured. This |
* entire state at a certain point, i.e. when a syntax error occured. This |
1462 |
* function will then walk ahead the potential parse tree starting from the |
* function will then walk ahead the potential parse tree starting from the |
1463 |
* current head of the given state stack. This function will call itself |
* current head of the given symbol stack. This function will call itself |
1464 |
* recursively to scan the individual parse tree branches. As soon as it hits |
* recursively to scan the individual parse tree branches. As soon as it hits |
1465 |
* on the next non-terminal grammar symbol in one parse tree branch, it adds the |
* on the next non-terminal grammar symbol in one parse tree branch, it adds the |
1466 |
* found non-terminal symbol to @a expectedSymbols and aborts scanning the |
* found non-terminal symbol to @a expectedSymbols and aborts scanning the |
1467 |
* respective tree branch further. If any local parser state is reached a second |
* respective tree branch further. If any local parser state is reached a second |
1468 |
* time, the respective parse tree is aborted to avoid any endless recursion. |
* time, the respective parse tree is aborted to avoid any endless recursion. |
1469 |
* |
* |
1470 |
* @param stack - current Bison (yacc) state stack to be examined |
* @param stack - current Bison (yacc) symbol stack to be examined |
1471 |
* @param expectedSymbols - will be filled with next expected grammar symbols |
* @param expectedSymbols - will be filled with next expected grammar symbols |
1472 |
* @param nextExpectedChars - just for internal purpose, due to the recursive |
* @param nextExpectedChars - just for internal purpose, due to the recursive |
1473 |
* implementation of this function, do supply an |
* implementation of this function, do supply an |
1482 |
#if DEBUG_BISON_SYNTAX_ERROR_WALKER |
#if DEBUG_BISON_SYNTAX_ERROR_WALKER |
1483 |
printf("\n"); |
printf("\n"); |
1484 |
for (int i = 0; i < depth; ++i) printf("\t"); |
for (int i = 0; i < depth; ++i) printf("\t"); |
1485 |
printf("State stack:"); |
printf("Symbol stack:"); |
1486 |
for (int i = 0; i < stack.size(); ++i) { |
for (int i = 0; i < stack.size(); ++i) { |
1487 |
printf(" %d", stack[i]); |
printf(" %d", stack[i]); |
1488 |
} |
} |
1625 |
continue; // duplicate state, ignore it to avoid endless recursions |
continue; // duplicate state, ignore it to avoid endless recursions |
1626 |
} |
} |
1627 |
|
|
1628 |
// "shift" / push the new state on the state stack and call this |
// "shift" / push the new state on the symbol stack and call this |
1629 |
// function recursively, and restore the stack after the recurse return |
// function recursively, and restore the stack after the recurse return |
1630 |
stackSize = stack.size(); |
stackSize = stack.size(); |
1631 |
nextExpectedCharsLen = nextExpectedChars.size(); |
nextExpectedCharsLen = nextExpectedChars.size(); |
1688 |
#if DEBUG_PUSH_PARSE |
#if DEBUG_PUSH_PARSE |
1689 |
//printf("\n"); |
//printf("\n"); |
1690 |
//for (int i = 0; i < depth; ++i) printf("\t"); |
//for (int i = 0; i < depth; ++i) printf("\t"); |
1691 |
printf("State stack:"); |
printf("Symbol stack:"); |
1692 |
for (int i = 0; i < stack.size(); ++i) { |
for (int i = 0; i < stack.size(); ++i) { |
1693 |
printf(" %d", stack[i]); |
printf(" %d", stack[i]); |
1694 |
} |
} |
1765 |
* Returns the amount of correct characters of given @a line from the left, |
* Returns the amount of correct characters of given @a line from the left, |
1766 |
* according to the LSCP grammar. |
* according to the LSCP grammar. |
1767 |
* |
* |
1768 |
* @param stack - a Bison symbol state stack to work with |
* @param stack - a Bison symbol stack to work with |
1769 |
* @param line - the input line to check |
* @param line - the input line to check |
1770 |
* @param bAutoCorrect - if true: try to correct obvious, trivial syntax errors |
* @param bAutoCorrect - if true: try to correct obvious, trivial syntax errors |
1771 |
*/ |
*/ |
1773 |
int i; |
int i; |
1774 |
for (i = 0; i < line.size(); ++i) { |
for (i = 0; i < line.size(); ++i) { |
1775 |
// since we might check the same parser state twice against the current |
// since we might check the same parser state twice against the current |
1776 |
// char here below, and since the state stack might be altered |
// char here below, and since the symbol stack might be altered |
1777 |
// (i.e. shifted or reduced) on syntax errors, we have to backup the |
// (i.e. shifted or reduced) on syntax errors, we have to backup the |
1778 |
// current state stack and restore it on syntax errors below |
// current symbol stack and restore it on syntax errors below |
1779 |
std::vector<YYTYPE_INT16> stackCopy = stack; |
std::vector<YYTYPE_INT16> stackCopy = stack; |
1780 |
if (yyValid(stackCopy, line[i])) { |
if (yyValid(stackCopy, line[i])) { |
1781 |
stack = stackCopy; |
stack = stackCopy; |
1813 |
YYTYPE_INT16* ss = (*param->ppStackBottom); |
YYTYPE_INT16* ss = (*param->ppStackBottom); |
1814 |
YYTYPE_INT16* sp = (*param->ppStackTop); |
YYTYPE_INT16* sp = (*param->ppStackTop); |
1815 |
int iStackSize = sp - ss + 1; |
int iStackSize = sp - ss + 1; |
1816 |
// copy and wrap parser's state stack into a convenient STL container |
// copy and wrap parser's symbol stack into a convenient STL container |
1817 |
std::vector<YYTYPE_INT16> stack; |
std::vector<YYTYPE_INT16> stack; |
1818 |
for (int i = 0; i < iStackSize; ++i) { |
for (int i = 0; i < iStackSize; ++i) { |
1819 |
stack.push_back(ss[i]); |
stack.push_back(ss[i]); |
1832 |
#define DEBUG_YY_AUTO_COMPLETE 0 |
#define DEBUG_YY_AUTO_COMPLETE 0 |
1833 |
|
|
1834 |
/** |
/** |
1835 |
* A set of parser state stacks. This type is used in yyAutoComplete() to keep |
* A set of parser symbol stacks. This type is used in yyAutoComplete() to keep |
1836 |
* track of all previous parser states, for detecting a parser state stack that |
* track of all previous parser states, for detecting a parser symbol stack that |
1837 |
* has already been before. Because if yyAutoComplete() reaches the exactly same |
* has already been before. Because if yyAutoComplete() reaches the exactly same |
1838 |
* parser state stack again, it means there is an endless recursion in that |
* parser symbol stack again, it means there is an endless recursion in that |
1839 |
* part of the grammar tree branch and shall not be evaluated any further, |
* part of the grammar tree branch and shall not be evaluated any further, |
1840 |
* because it would end up in an endless loop otherwise. |
* because it would end up in an endless loop otherwise. |
1841 |
* |
* |
1847 |
|
|
1848 |
/** |
/** |
1849 |
* Generates and returns an auto completion string for the current parser |
* Generates and returns an auto completion string for the current parser |
1850 |
* state given by @a stack. |
* state given by @a stack. That means, this function will return the longest |
1851 |
|
* sequence of characters that is uniqueley expected to be sent next by the LSCP |
1852 |
|
* client. Or in other words, if the LSCP client would send any other |
1853 |
|
* character(s) than returned here, it would result in a syntax error. |
1854 |
|
* |
1855 |
|
* This function takes a Bison symbol @a stack as argument, reflecting the |
1856 |
|
* current Bison parser state, and evaluates the individual grammar tree |
1857 |
|
* branches starting from that particular position. It walks along the grammar |
1858 |
|
* tree as long as there is only one possible tree branch and assembles a string |
1859 |
|
* of input characters that would lead to that walk through the grammar tree. As |
1860 |
|
* soon as a position in the grammar tree is reached where there are multiple |
1861 |
|
* possible tree branches, this algorithm will stop, since the user could have |
1862 |
|
* multiple possible valid characters he could type at that point, thus auto |
1863 |
|
* completion would no longer be unique at that point. |
1864 |
* |
* |
1865 |
* Regarding @a history argument: read the description on YYStackHistory for the |
* Regarding @a history argument: read the description on YYStackHistory for the |
1866 |
* purpose behind this argument. |
* purpose behind this argument. |
1867 |
* |
* |
1868 |
* @param stack - current Bison (yacc) state stack to create auto completion for |
* @param stack - current Bison (yacc) symbol stack to create auto completion for |
1869 |
* @param history - only for internal purpose, keeps a history of all previous parser state stacks |
* @param history - only for internal purpose, keeps a history of all previous |
1870 |
|
* parser symbol stacks (just for avoiding endless recursion in |
1871 |
|
* this auto completion algorithm) |
1872 |
* @param depth - just for internal debugging purposes |
* @param depth - just for internal debugging purposes |
1873 |
* @returns auto completion for current, given parser state |
* @returns auto completion for current, given parser state |
1874 |
*/ |
*/ |
1992 |
/** |
/** |
1993 |
* If LSCP shell mode is enabled for the respective LSCP client connection, then |
* If LSCP shell mode is enabled for the respective LSCP client connection, then |
1994 |
* this function is called on every new byte received from that client. It will |
* this function is called on every new byte received from that client. It will |
1995 |
* check the current total input line and reply to the LSCP shell for providing |
* check the current total input line and reply to the LSCP shell with a |
1996 |
* colored syntax highlighting and potential auto completion in the shell. |
* specially crafted string, which allows the shell to provide colored syntax |
1997 |
|
* highlighting and potential auto completion in the shell. |
1998 |
* |
* |
1999 |
* It also performs auto correction of obvious & trivial syntax mistakes if |
* It also performs auto correction of obvious & trivial syntax mistakes if |
2000 |
* requested. |
* requested. |
2001 |
* |
* |
2002 |
* The return value of this function will be sent to the client. It contains one |
* The return value of this function will be sent to the client. It contains one |
2003 |
* line specially formatted for the LSCP shell, which can easily be processed by |
* line specially formatted for the LSCP shell application, which can easily be |
2004 |
* the client/shell for gettings its necessary informations like which part of |
* processed by the client/shell for extracting its necessary informations like |
2005 |
* the current command line is syntactically correct, which part is incorrect, |
* which part of the current command line is syntactically correct, which part |
2006 |
* what could be auto completed right now, etc. |
* is incorrect, what could be auto completed right now, etc. So all the heavy |
2007 |
|
* grammar evaluation tasks are peformed by the LSCP server for the LSCP shell |
2008 |
|
* application (which is desgined as a thin client), so the LSCP shell |
2009 |
|
* application will only have to show the results of the LSCP server's |
2010 |
|
* evaluation to the user on the screen. |
2011 |
* |
* |
2012 |
* @returns LSCP shell response line to be returned to the client |
* @returns LSCP shell response line to be returned to the client |
2013 |
*/ |
*/ |
2037 |
|
|
2038 |
// get a clean parser stack to the last valid parse position |
// get a clean parser stack to the last valid parse position |
2039 |
// (due to the appended '\n' character above, and on syntax errors, the |
// (due to the appended '\n' character above, and on syntax errors, the |
2040 |
// state stack might be in undesired, i.e. reduced state) |
// symbol stack might be in undesired, i.e. reduced state) |
2041 |
stack.clear(); |
stack.clear(); |
2042 |
stack.push_back(0); // every Bison symbol stack starts with state zero |
stack.push_back(0); // every Bison symbol stack starts with state zero |
2043 |
l = line.substr(0, n); |
l = line.substr(0, n); |