[Avida-SVN] r1743 - development/source/script
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Tue Jul 3 08:46:20 PDT 2007
Author: brysonda
Date: 2007-07-03 11:46:20 -0400 (Tue, 03 Jul 2007)
New Revision: 1743
Modified:
development/source/script/AvidaScript.h
development/source/script/cParser.cc
development/source/script/cParser.h
Log:
First pass ArgumentList, CodeBlock, FunctionDefine, FunctionHeader, IfStatement, VarDeclare, VarDeclareList, and WhileStatement.
Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h 2007-07-02 00:55:51 UTC (rev 1742)
+++ development/source/script/AvidaScript.h 2007-07-03 15:46:20 UTC (rev 1743)
@@ -25,7 +25,7 @@
#ifndef AvidaScript_h
#define AvidaScript_h
-enum eASTokens {
+typedef enum eASTokens {
SUPPRESS = 1,
ENDL,
COMMA,
@@ -99,8 +99,9 @@
STRING,
CHAR,
- UNKNOWN
-};
+ UNKNOWN,
+ INVALID
+} ASToken_t;
typedef enum eASParseErrors {
AS_PARSE_ERR_UNEXPECTED_TOKEN,
Modified: development/source/script/cParser.cc
===================================================================
--- development/source/script/cParser.cc 2007-07-02 00:55:51 UTC (rev 1742)
+++ development/source/script/cParser.cc 2007-07-03 15:46:20 UTC (rev 1743)
@@ -159,7 +159,9 @@
loose_block: ARR_OPEN statement_list ARR_CLOSE
if_block: CMD_IF PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ENDIF
- | CMD_IF PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ELSE statement_list CMD_ENDIF
+ | CMD_IF PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ELSE lineterm statement_list CMD_ENDIF
+ | CMD_IF PREC_OPEN expr PREC_CLOSE loose_block CMD_ENDIF
+ | CMD_IF PREC_OPEN expr PREC_CLOSE loose_block CMD_ELSE loose_block CMD_ENDIF
while_block: CMD_WHILE PREC_OPEN expr PREC_CLOSE lineterm statement_list CMD_ENDWHILE
| CMD_WHILE PREC_OPEN expr PREC_CLOSE loose_block
@@ -169,7 +171,6 @@
var_declare: type_def ID
| type_def ID ASSIGN expr
- | type_def ID PREC_OPEN expr PREC_CLOSE
| type_def ID PREC_OPEN argument_list PREC_CLOSE
var_declare_list: var_declare_list_1
@@ -191,6 +192,17 @@
#define PARSE_ERROR(x) reportError(AS_PARSE_ERR_ ## x, __LINE__);
#define PARSE_UNEXPECT() { if (currentToken()) { PARSE_ERROR(UNEXPECTED_TOKEN); } else { PARSE_ERROR(EOF); } }
+
+cParser::cParser(cASLibrary* library)
+: m_library(library)
+, m_eof(false)
+, m_success(true)
+, m_cur_tok(INVALID)
+, m_next_tok(INVALID)
+, m_err_eof(false)
+{
+}
+
bool cParser::Parse(cFile& input)
{
m_lexer = new cLexer(input.GetFileStream());
@@ -205,6 +217,18 @@
}
+ASToken_t cParser::nextToken()
+{
+ if (m_next_tok != INVALID) {
+ m_cur_tok = m_next_tok;
+ m_next_tok = INVALID;
+ } else {
+ m_cur_tok = (ASToken_t)m_lexer->yylex();
+ }
+ return m_cur_tok;
+}
+
+
cASTNode* cParser::parseArrayUnpack()
{
cASTNode* au = NULL;
@@ -236,6 +260,18 @@
return au;
}
+cASTNode* cParser::parseArgumentList()
+{
+ cASTNode* al = NULL;
+
+ parseExpression();
+ while (currentToken() == COMMA) {
+ parseExpression();
+ }
+
+ return al;
+}
+
cASTNode* cParser::parseAssignment()
{
cASTNode* an = NULL;
@@ -252,6 +288,24 @@
return NULL;
}
+cASTNode* cParser::parseCodeBlock(bool& loose)
+{
+ cASTNode* cb = NULL;
+
+ nextToken();
+ if (currentToken() == ARR_OPEN) {
+ loose = true;
+ cb = parseLooseBlock();
+ } else if (currentToken() == SUPPRESS || currentToken() == ENDL) {
+ cb = parseStatementList();
+ } else {
+ PARSE_UNEXPECT();
+ return cb;
+ }
+
+ return cb;
+}
+
cASTNode* cParser::parseExpression()
{
// @todo
@@ -295,39 +349,109 @@
return fs;
}
- nextToken();
- if (currentToken() == ARR_OPEN) {
- parseLooseBlock();
- } else if (currentToken() == SUPPRESS || currentToken() == ENDL) {
- parseStatementList();
- if (currentToken() != CMD_ENDFOREACH) {
- PARSE_UNEXPECT();
- return fs;
- }
- } else {
- PARSE_UNEXPECT();
- return fs;
- }
+ bool loose = false;
+ parseCodeBlock(loose);
+ if (!loose && currentToken() != CMD_ENDFOREACH) PARSE_UNEXPECT();
return fs;
}
-cASTNode* cParser::parseFunctionDeclare()
+cASTNode* cParser::parseFunctionDefine()
{
- // @todo
- return NULL;
+ cASTNode* fd = parseFunctionHeader(false);
+
+ bool loose = false;
+ parseCodeBlock(loose);
+ if (!loose && currentToken() != CMD_ENDFUNCTION) {
+ PARSE_UNEXPECT();
+ return fd;
+ }
+
+ return fd;
}
-cASTNode* cParser::parseFunctionDefine()
+cASTNode* cParser::parseFunctionHeader(bool declare)
{
- // @todo
- return NULL;
+ cASTNode* fd = NULL;
+
+ switch (nextToken()) {
+ case TYPE_ARRAY:
+ case TYPE_CHAR:
+ case TYPE_FLOAT:
+ case TYPE_INT:
+ case TYPE_MATRIX:
+ case TYPE_STRING:
+ case TYPE_VOID:
+ break;
+ case ID:
+ if (peekToken() != REF) {
+ nextToken();
+ PARSE_UNEXPECT();
+ return fd;
+ }
+ break;
+
+ default:
+ PARSE_UNEXPECT();
+ return fd;
+ }
+
+ if (nextToken() != ID) {
+ PARSE_UNEXPECT();
+ return fd;
+ }
+
+ if (nextToken() != PREC_OPEN) {
+ PARSE_UNEXPECT();
+ return fd;
+ }
+
+ nextToken();
+ if (declare) {
+ parseVarDeclareList();
+ } else {
+ parseArgumentList();
+ }
+
+ if (nextToken() != PREC_CLOSE) {
+ PARSE_UNEXPECT();
+ return fd;
+ }
+
+ return fd;
}
cASTNode* cParser::parseIfStatement()
{
- // @todo
- return NULL;
+ cASTNode* is = NULL;
+
+ if (nextToken() != PREC_OPEN) {
+ PARSE_UNEXPECT();
+ return is;
+ }
+
+ nextToken();
+ parseExpression();
+
+ if (currentToken() != PREC_CLOSE) {
+ PARSE_UNEXPECT();
+ return is;
+ }
+
+ bool loose = false;
+ parseCodeBlock(loose);
+ if (currentToken() == CMD_ELSE) {
+ parseCodeBlock(loose);
+ if (!loose && currentToken() != CMD_ENDIF) {
+ PARSE_UNEXPECT();
+ return is;
+ }
+ } else if (!loose && currentToken() != CMD_ENDIF) {
+ PARSE_UNEXPECT();
+ return is;
+ }
+
+ return is;
}
cASTNode* cParser::parseIDStatement()
@@ -374,7 +498,7 @@
parseArrayUnpack();
break;
case CMD_FUNCTION:
- parseFunctionDeclare();
+ parseFunctionHeader();
break;
default:
PARSE_UNEXPECT();
@@ -432,6 +556,7 @@
break;
case REF:
parseRefStatement();
+ CHECK_LINETERM();
break;
case SUPPRESS:
break;
@@ -457,19 +582,97 @@
cASTNode* cParser::parseVarDeclare()
{
- // @todo
- return NULL;
+ cASTNode* vd = NULL;
+
+ switch (currentToken()) {
+ case TYPE_ARRAY:
+ case TYPE_CHAR:
+ case TYPE_FLOAT:
+ case TYPE_INT:
+ case TYPE_MATRIX:
+ case TYPE_STRING:
+ break;
+ case ID:
+ if (nextToken() != REF) {
+ PARSE_UNEXPECT();
+ return vd;
+ }
+ break;
+
+ default:
+ PARSE_UNEXPECT();
+ return vd;
+ }
+
+ if (nextToken() != ID) {
+ PARSE_UNEXPECT();
+ return vd;
+ }
+
+ switch (nextToken()) {
+ case ASSIGN:
+ nextToken();
+ parseExpression();
+ break;
+ case PREC_OPEN:
+ nextToken();
+ parseArgumentList();
+ if (currentToken() != PREC_CLOSE) {
+ PARSE_UNEXPECT();
+ return vd;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return vd;
}
+cASTNode* cParser::parseVarDeclareList()
+{
+ cASTNode* vl = NULL;
+
+ parseVarDeclare();
+ while (currentToken() == COMMA) {
+ parseVarDeclare();
+ }
+
+ return vl;
+}
+
cASTNode* cParser::parseWhileStatement()
{
- // @todo
- return NULL;
+ cASTNode* ws = NULL;
+
+ if (nextToken() != PREC_OPEN) {
+ PARSE_UNEXPECT();
+ return ws;
+ }
+
+ nextToken();
+ parseExpression();
+
+ if (currentToken() != PREC_CLOSE) {
+ PARSE_UNEXPECT();
+ return ws;
+ }
+
+ bool loose = false;
+ parseCodeBlock(loose);
+ if (!loose && currentToken() != CMD_ENDWHILE) {
+ PARSE_UNEXPECT();
+ return ws;
+ }
+
+ return ws;
}
bool cParser::checkLineTerm(cASTNode* node)
{
+ nextToken();
if (currentToken() == SUPPRESS) {
// @todo - mark output as suppressed
return true;
Modified: development/source/script/cParser.h
===================================================================
--- development/source/script/cParser.h 2007-07-02 00:55:51 UTC (rev 1742)
+++ development/source/script/cParser.h 2007-07-03 15:46:20 UTC (rev 1743)
@@ -59,31 +59,38 @@
bool m_eof;
bool m_success;
- int m_cur_tok;
+ ASToken_t m_cur_tok;
+ ASToken_t m_next_tok;
bool m_err_eof;
- cParser();
+ cParser(); // @not_implemented
+ cParser(const cParser&); // @not_implemented
+ cParser& operator=(const cParser&); // @not_implemented
+
+
public:
- cParser(cASLibrary* library) : m_library(library), m_eof(false), m_success(true), m_cur_tok(0), m_err_eof(false) { ; }
+ cParser(cASLibrary* library);
bool Parse(cFile& input);
-
void Accept(cASTVisitor& visitor);
private:
- inline int currentToken() { return m_cur_tok; }
- inline int nextToken();
+ inline ASToken_t currentToken() { return m_cur_tok; }
+ ASToken_t nextToken();
+ inline ASToken_t peekToken();
+ cASTNode* parseArgumentList();
cASTNode* parseArrayUnpack();
cASTNode* parseAssignment();
cASTNode* parseCallExpression();
+ cASTNode* parseCodeBlock(bool& loose);
cASTNode* parseExpression();
cASTNode* parseForeachStatement();
- cASTNode* parseFunctionDeclare();
cASTNode* parseFunctionDefine();
+ cASTNode* parseFunctionHeader(bool declare = true);
cASTNode* parseIDStatement();
cASTNode* parseIfStatement();
cASTNode* parseLooseBlock();
@@ -91,6 +98,7 @@
cASTNode* parseReturnStatement();
cASTNode* parseStatementList();
cASTNode* parseVarDeclare();
+ cASTNode* parseVarDeclareList();
cASTNode* parseWhileStatement();
bool checkLineTerm(cASTNode* node);
@@ -99,10 +107,10 @@
};
-inline int cParser::nextToken()
+inline ASToken_t cParser::peekToken()
{
- m_cur_tok = m_lexer->yylex();
- return m_cur_tok;
+ if (m_next_tok == INVALID) m_next_tok = (ASToken_t)m_lexer->yylex();
+ return m_next_tok;
}
More information about the Avida-cvs
mailing list