📄 lexer.c
字号:
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 + -