⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexer.c

📁 Coware的LISA指令集描述语言开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
				node->args->next = work;

				// parsing for optional declaration list...
				next = work;
				work = parse();
				while ( strcmp( work->element, "," ) == 0 )
				{
					// destroy ',' token
					destroyNode( work );
					// parse for identifier...
					work = parse();
					if ( work->type != LISA_TYPE_IDENTIFIER )
						syntaxError( "missing identifier" );
					next->next = work;
					next = work;
					// check if ","
					work = parse();
				}
				pushbackNode( work );

				// parse for ')'...
				work = parse();
				if ( work->type != LISA_TYPE_CLOSE_ROUND_BRACKET )
					syntaxError( "missing ')'" );
				destroyNode( work );

				// parsing optional ':' for TAG type statement...
				work = parse();
				if ( work->type == LISA_TYPE_COLON )
				{
					node->type = LISA_TYPE_TAGKEYWORD;
					break;
				}
				else
				{
					pushbackNode( work );
				}

				// parse for BLOCK...
				work = lex( LISA_SCOPE_BLOCK | LISA_SCOPE_STATEMENT | LISA_SCOPE_EXPRESSION );
				node->args->args = work;
				break;
			}

			// function name-identifier ( arg-list )
			//    block
			//
			//                   function
			//                     /  |
			//      name-identifier    ...
			//            /  |
			//       block    arg-list
			//
			// inline declaration:
			//
			// function name-identifier ( arg-list ) is expression;
			//
			if ( strcmp( element, "function" ) == 0 )
			{
				// parse for name-identifier...
				work = parse();
				if ( work->type != LISA_TYPE_IDENTIFIER )
					syntaxError( "missing function name" );
				node->args = work;

				// parse for '('...
				work = parse();
				if ( work->type != LISA_TYPE_OPEN_ROUND_BRACKET )
					syntaxError( "missing '('" );
				destroyNode( work );

				// parse for optional arg list...
				work = lex( LISA_SCOPE_CONDITION | LISA_SCOPE_EMPTY );
				if ( emptyNode( work ) )
				{
					destroyNode( work );
					work = NULL;
				}
				node->args->next = work;

				// parse for ')'...
				work = parse();
				if ( work->type != LISA_TYPE_CLOSE_ROUND_BRACKET )
					syntaxError( "missing ')'" );
				destroyNode( work );

				// parse for 'is' keyword...
				work = parse();
				if ( strcmp( work->element, "is" ) == 0 )
				{
					// free the 'is' keyword...
					destroyNode( work );
					// get the expression...
					work = lex( LISA_SCOPE_CONDITION );
					// creating 'return' statement...
					node->args->args = createNode();
					strcpy( node->args->args->element, "return" );
					node->args->args->type = LISA_TYPE_KEYWORD;
					// linking expression to return statement...
					node->args->args->args = work;
					// parsing for end of statement...
					work = lex( LISA_SCOPE_SEMICOLON );
					destroyNode( work );
				}
				else
				{
					pushbackNode( work );
					// parse for BLOCK...
					work = lex( LISA_SCOPE_BLOCK | LISA_SCOPE_STATEMENT | LISA_SCOPE_EXPRESSION );
					node->args->args = work;
				}

				break;
			}

			// global declaration;
			//
			//                    global
			//                     / |
			//      var-declaration   ...
			//
			if ( strcmp( element, "global" ) == 0 )
			{
				// parse for 'var keyword...
				work = parse();
				if ( ( work->type != LISA_TYPE_KEYWORD ) ||
					 ( strcmp( work->element, "var" ) != 0 ) )
				{
					syntaxError( "only var declarations can be globals" );
				}
				pushbackNode( work );
				work = lex( LISA_SCOPE_STATEMENT );
				node->args = work;

				break;
			}

			// if ( condition ) [ { ] true-statement [ } ]
			// [ else [ { ] false-statement [ } ] ]
			//
			//                     if
			//                    /  |
			//               empty
			//               /   |
			//      condition     empty
			//                    /   |
			//                true   [ false ]
			//
			if ( strcmp( element, "if" ) == 0 )
			{
				// creating APT skeleton...
				node->args       = createNode();
				node->args->next = createNode();

				// parse for '('...
				work = parse();
				if ( work->type != LISA_TYPE_OPEN_ROUND_BRACKET )
					syntaxError( "missing '('" );

				// parsing CONDITION...
				work = lex( LISA_SCOPE_CONDITION );
				node->args->args = work;

				// parse for ')'...
				work = parse();
				if ( work->type != LISA_TYPE_CLOSE_ROUND_BRACKET )
					syntaxError( "missing ')'" );

				// parsing optional ':' for TAG type statement...
				work = parse();
				if ( work->type == LISA_TYPE_COLON )
				{
					node->type = LISA_TYPE_TAGKEYWORD;
					break;
				}
				else
				{
					pushbackNode( work );
				}

				// parsing TRUE-STATEMENT
				work = lex( LISA_SCOPE_BLOCK | LISA_SCOPE_STATEMENT | LISA_SCOPE_EXPRESSION );
				node->args->next->args = work;

				// parsing optional ELSE...
				work = parse();
				if ( work->type != LISA_TYPE_KEYWORD )
				{
					pushbackNode( work );
					break;
				}
				if ( strcmp( work->element, "else" ) != 0 )
				{
					pushbackNode( work );
					break;
				}

				// parsing FALSE-STATEMENT
				work = lex( LISA_SCOPE_BLOCK | LISA_SCOPE_STATEMENT | LISA_SCOPE_EXPRESSION );
				node->args->next->next = work;

				break;
			}

			// parameter declaration;
			//
			//                   parameter
			//                     /  |
			//      var-declaration    ...
			//
			if ( strcmp( element, "parameter" ) == 0 )
			{
				// parse for 'var keyword...
				work = parse();
				if ( ( work->type != LISA_TYPE_KEYWORD ) ||
					 ( strcmp( work->element, "var" ) != 0 ) )
				{
					syntaxError( "parmeters may be only variants" );
				}
				pushbackNode( work );
				work = lex( LISA_SCOPE_STATEMENT );
				node->args = work;

				break;
			}

			// return [expression];
			//
			//                    return
			//                     /  |
			//         [ expression ]  ...
			//
			if ( strcmp( element, "return" ) == 0 )
			{
				// parse for optional expression...
				work = lex( LISA_SCOPE_CONDITION | LISA_SCOPE_EMPTY );
				if ( emptyNode( work ) )
				{
					destroyNode( work );
					work = NULL;
				}
				node->args = work;

				// parse for ';'...
				work = lex( LISA_SCOPE_SEMICOLON );
				destroyNode( work );

				break;
			}

			// switch ( condition )
			// '{'
			// 		{ case value: {block} }
			//		[ default: {block} ]
			// '}'
			//
			//                        switch
			//                        /  |
			//                   empty
			//                   /  |
			//          condition  { case }
			//                      /   |
			//                 value   [ default ]
			//                  /        /
			//             block    block
			//
			if ( strcmp( element, "switch" ) == 0 )
			{
				// creating APT skeleton...
				node->args = createNode();

				// parse for '('...
				work = parse();
				if ( work->type != LISA_TYPE_OPEN_ROUND_BRACKET )
					syntaxError( "missing '('" );

				// parsing CONDITION...
				work = lex( LISA_SCOPE_CONDITION );
				node->args->args = work;

				// parse for ')'...
				work = parse();
				if ( work->type != LISA_TYPE_CLOSE_ROUND_BRACKET )
					syntaxError( "missing ')'" );

				// parsing optional ':' for TAG type statement...
				work = parse();
				if ( work->type == LISA_TYPE_COLON )
				{
					node->type = LISA_TYPE_TAGKEYWORD;
					destroyNode( work );
					// NOTE: (2002-09-12 Gabriele Budelacci)
					//	I must lex next statement (I'm waiting for a
					//	'case:' or 'default' statement) to prevent
					//	any other token after a 'switch:'.
					//	In future, the search scope for lex may be
					//	expressly mentioned.
					work = lex( LISA_SCOPE_STATEMENT );
					node->next = work;
					// NOTE: (2002-09-12 Gabriele Budelacci)
					//	I must end the statement list with an empty node.
					node->next->next = createNode();
					break;
				}
				else
				{
					pushbackNode( work );
				}

				// parse for '{'...
				work = parse();
				if ( work->type != LISA_TYPE_OPEN_BLOCK_BRACKET )
					syntaxError( "missing '{'" );

				tmp = node->args;
				// parsing optional sequence of case statements
				work = parse();
				while ( strcmp( work->element, "case" ) == 0 )
				{
					tmp->next = work;

					// parse for value...
					work = parse();
					if ( ( work->type != LISA_TYPE_NUMBER ) &&
					     ( work->type != LISA_TYPE_STRING )  )
						syntaxError( "missing fixed value" );

					tmp->next->args = work;

					// parse for ':'...
					work = parse();
					if ( work->type != LISA_TYPE_COLON )
						syntaxError( "missing ':'" );

					// parse for optional block...
					tmp->next->args->args = lex( LISA_SCOPE_BLOCK | LISA_SCOPE_EMPTY );

					// parse next block...
					tmp = tmp->next;
					work = parse();
				}

				// test for optional default statement...
				if ( strcmp( work->element, "default" ) == 0 )
				{
					tmp->next = work;

					// parse for ':'...
					work = parse();
					if ( work->type != LISA_TYPE_COLON )
						syntaxError( "missing ':'" );

					// parse for optional block...
					tmp->next->args = lex( LISA_SCOPE_BLOCK | LISA_SCOPE_STATEMENT | LISA_SCOPE_EXPRESSION | LISA_SCOPE_EMPTY );
				}
				else
				{
					pushbackNode( work );
				}

				// parse for '}'...
				work = parse();
				if ( work->type != LISA_TYPE_CLOSE_BLOCK_BRACKET )
					syntaxError( "missing '}'" );

				break;
			}

			// transaction
			// '{' statement '}'
			//
			//              transaction
			//               /     |
			//         statement
			//
			if ( strcmp( element, "transaction" ) == 0 )
			{
				// parsing STATEMENT
				work = lex( LISA_SCOPE_BLOCK );
				node->args = work;

				break;
			}

			// while ( condition )
			// [ { ] statement [ } ]
			//
			//                     while
			//                      / |
			//                 empty
			//                 /   |
			//        condition     statement
			//
			if ( strcmp( element, "while" ) == 0 )
			{
				// creating APT skeleton...
				node->args       = createNode();

				work = parse();
				if ( work->type != LISA_TYPE_OPEN_ROUND_BRACKET )
					syntaxError( "missing '('" );

				// parsing CONDITION...
				work = lex( LISA_SCOPE_CONDITION | LISA_SCOPE_EMPTY );
				if ( emptyNode( work ) )
				{
					destroyNode( work );
					work = NULL;
				}
				node->args->args = work;

				work = parse();
				if ( work->type != LISA_TYPE_CLOSE_ROUND_BRACKET )
					syntaxError( "missing ')'" );

				// parsing optional ':' for TAG type statement...
				work = parse();
				if ( work->type == LISA_TYPE_COLON )
				{
					node->type = LISA_TYPE_TAGKEYWORD;
					break;
				}
				else
				{
					pushbackNode( work );
				}

				// parsing STATEMENT
				work = lex( LISA_SCOPE_BLOCK | LISA_SCOPE_STATEMENT | LISA_SCOPE_EXPRESSION );
				node->args->next = work;

				break;
			}

			break;
		}

		case LISA_TYPE_NUMBER:
		case LISA_TYPE_STRING:
		{
			if ( ! ( scope & ( LISA_SCOPE_EXPRESSION | LISA_SCOPE_CONDITION ) ) )
			{
				// return an empty node if EMPTY required...
				if ( scope & LISA_SCOPE_EMPTY )
				{
					pushbackNode( node );
					return createNode();
				}
				// else, stop compiling...
				syntaxError( "no value required" );
			}

			// parse for optional operator...
			work = parse();
			if ( work->type == LISA_TYPE_OPERATOR )
			{
				node->next = work;
			}
			else
			{
				pushbackNode( work );
				if ( scope & LISA_SCOPE_EXPRESSION )
					work = lex( LISA_SCOPE_SEMICOLON );
				break;
			}

			work = lex( LISA_SCOPE_CONDITION | LISA_SCOPE_EMPTY );
			if ( emptyNode( work ) )
			{
				destroyNode( work );
				work = NULL;
			}
			node->next->next = work;

			if ( scope & LISA_SCOPE_EXPRESSION )
			{
				work = lex( LISA_SCOPE_SEMICOLON );
				destroyNodeR( work );

				// creating empty expression node...
				work = createNode();
				work->type = LISA_TYPE_EXPRESSION;
				// ...and returning it...
				work->args = node;
				node = work;
			}

			break;
		}

		case LISA_TYPE_OPERATOR:
		{
			if ( ! ( scope & ( LISA_SCOPE_EXPRESSION | LISA_SCOPE_CONDITION ) ) )
			{
				// return an empty node if EMPTY required...
				if ( scope & LISA_SCOPE_EMPTY )
				{
					pushbackNode( node );
					return createNode();
				}
				// else, stop compiling...
				syntaxError( "no value required" );
			}

			// parsing the rest of the EXPRESSION/CONDITION...
			work = lex( LISA_SCOPE_CONDITION );
			node->next = work;

			if ( scope & LISA_SCOPE_EXPRESSION )
			{
				work = lex( LISA_SCOPE_SEMICOLON );
				destroyNodeR( work );

				// creating empty expression node...
				work = createNode();
				work->type = LISA_TYPE_EXPRESSION;
				// ...and returning it...
				work->args = node;
				node = work;
			}

			break;
		}

		case LISA_TYPE_SEMICOLON:
		{
			if ( ! ( scope & LISA_SCOPE_SEMICOLON ) )
			{
				// return an empty node if EMPTY required...
				if ( scope & LISA_SCOPE_EMPTY )
				{
					pushbackNode( node );
					return createNode();
				}
				// else, stop compiling...
				syntaxError( "no ';' required" );
			}
			break;
		}


		default:
		{
			// return an empty node if EMPTY required...
			if ( scope & LISA_SCOPE_EMPTY )
			{
				pushbackNode( node );
				return createNode();
			}

			// error on empty node...
			if ( emptyNode( node ) )
				syntaxError( "empty token" );

			// else, stop compiling...
			syntaxError( "bad token" );
		}
	}

	return node;
}//lex

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -