Simple logical Expression Lexical analyzer
The logical expressions to be parsed are as follows: EXISTS (x) (missile (x) and owns (Father (Nono), part_of (x))) => sells (West,x,nono)
To handle logical expressions, you must first extract parts of the logical expression: keywords (and, or, not, ForAll, EXISTS, =>), predicates, and arguments, and must be removed for extra spaces in an expression. This work is done by a lexical analyzer.
The most basic part of the lexical analyzer is a custom node, defined as follows: Class node
... {
Public
VARIABLEs
Enum NodeType ... {KEYWORD, predicate, PARAM}; Types of the node.
Static wstring keyword[];
NodeType type;
Wstring content; Content of the node.
int level; The level of the node,for example:
Owns (nono,sub (x))---"Owns" in Level 0, "Nono" "Sub" in Level 1 and X at level 2.
Functions
Node ();
Node (wstring con,nodetype type_=keyword,int lev=0);
~node ();
Virtual node& operator= (node&); Overrides of Operator=
Protected
} ;
Node has three main parts: the node content, node type, node level (for further analysis of the extracted expression).
A list of linked lists is also defined:
typedef list<node> NodeList; Define List.
The linked list is used to store the entire logical expression.
It also defines a class parser, encapsulates nodelist, and is used to manipulate logical expressions.
Class Parser
... {
Public
VARIABLEs
NodeList list;
node* node;
Functions
Parser () ... {node=null;};
~parser ();
node* Parse (wstring str,int cur_pos=0); function to parse a string.
Private
} ;
The core function of the lexical analyzer is node* Parser::P arse (wstring str,int cur_pos), which is mainly for the analysis of ' (', ', ', ', and ') in the logical expression, the flowchart is as follows:
The results of the operation are as follows:
The
Analysis results are expressed as trees: the same level of nodes represents the same level, and the parameters are higher than the rank of the predicate, such as the level of missile in missile (x) is 0, and X is Level 1. After analysis, each node is stored in parser.list, and each node can be inserted into the corresponding position of the tree according to the level property of the node of the linked list.
analyzing the above logical expressions, the levels of each node are as follows:
missile x and owns nono sub x => sells west x Nono
& nbsp; 0 1 0 0 1 1 2 0 0 1 1 1
visible, using the stack to assist in inserting nodes into the tree is the ideal method. The idea is as follows: The tvi_root of the tree is pressed stack; If the current node is more than its previous node, pressing the previous node to the stack; If the current node level is less than the previous node, the first node level and the current node level difference; If the current node level is equal to the previous node level, neither the stack nor stack. The parent node of each current node is the top element of the stack.
The source code is as follows:
/**/ //////////////////////////////////////////////////
//
Function Name:parse
Input:a wstring (MUST),
The start position of being parsed (choiced).
Output:a parsed list ' s head.
//
/**/ //////////////////////////////////////////////////
Node * Parser::P arse (wstring str, int cur_pos)
... {
int start=cur_pos;
node* Tmpnode=null;
wchar_t pstr[40]=l ""; Temp var to record words.
int k=0; Used together with PSTR.
int level=0;
int space_pos=0;
Deal with the keywords a propositional fuction.
Such as not, EXISTS (x), ForAll (y) and.
Example:exists (x) (missile (x) and owns (nono,x)) => sells (West,x,nono)
Example:not (missile (x)) and owns (Nono,sub (x)) => sells (West,x,nono)