📄 parser.g
字号:
break;
case GROUP:
currentTerm->iclType = icl_group_type;
#ifdef NORMAL_GC
gt = (ICLGroupType*)GC_debug_malloc(sizeof(ICLGroupType), __FILE__, __LINE__);
#else
gt = (ICLGroupType*)malloc(sizeof(ICLGroupType));
#endif
gt->list = NULL;
gt->startChar = currentAST->tokenData[0];
free(currentAST->tokenData);
gt->separator = strdup(",");
currentTerm->p = gt;
currentTerm->len = sizeof(gt);
if(debug) {
printf("Found group\n");
}
break;
case ICLDATAQ:
currentTerm->iclType = icl_dataq_type;
currentTerm->p = currentAST->tokenData;
currentTerm->len = currentAST->tokenLen;
currentTerm->glibAlloc = 1;
if(debug) {
printf("Found icldataq of len %i\n", currentTerm->len);
}
break;
default:
fprintf(stderr, "Parser attempted to make ICLTerm from type %i\n", currentAST->type);
parser_error = TRUE;
g_ptr_array_free(termList, TRUE);
g_ptr_array_free(parentsList, TRUE);
return FALSE;
}
if(debug) {
printf("Created term at %p with type %i\n", currentTerm, currentTerm->iclType);
}
if(currentAST != root) {
if(debug) {
printf("Attempting to add term at %p to parent %p\n", (ICLTerm*)g_ptr_array_index(termList, parentIndex), (ICLTerm*)g_ptr_array_index(termList, parentIndex - 1));
}
icl_addChild((ICLTerm*)g_ptr_array_index(termList, parentIndex - 1), (ICLTerm*)g_ptr_array_index(termList, parentIndex));
}
/* Check if we go down or right or up */
if(currentAST->down != NULL) {
g_ptr_array_add(parentsList, currentAST->down);
++parentIndex;
continue;
}
else if(currentAST->right != NULL) {
(void)g_ptr_array_remove_index(parentsList, parentIndex);
(void)g_ptr_array_remove_index(termList, parentIndex);
g_ptr_array_add(parentsList, currentAST->right);
/* parentIndex stays the same, since we removed and added one */
}
else {
/* both down and right are NULL--we're at a leaf */
/* Keep going up the tree until we get to a non-NULL
* right, or we hit the root of the tree
*/
int foundSibling = FALSE;
while(parentIndex > 0){
(void)g_ptr_array_remove_index(parentsList, parentIndex);
(void)g_ptr_array_remove_index(termList, parentIndex);
--parentIndex;
currentAST = g_ptr_array_index(parentsList, parentIndex);
if(currentAST->right == NULL) {
continue;
}
else {
foundSibling = TRUE;
break;
}
}
if(parentIndex == 0) {
/* done */
*result = (ICLTerm*)g_ptr_array_remove_index(termList, 0);
g_ptr_array_free(termList, TRUE);
g_ptr_array_free(parentsList, TRUE);
termList = NULL;
parentsList = NULL;
if(debug) {
printf("found ICLTerm\n");
}
parser_error = FALSE;
return TRUE;
}
else if(foundSibling == TRUE) {
/* keep making ICLTerm tree */
/* remove the current sibling and replace with the new one */
(void)g_ptr_array_remove_index(parentsList, parentIndex);
(void)g_ptr_array_remove_index(termList, parentIndex);
g_ptr_array_add(parentsList, currentAST->right);
continue;
}
else {
fprintf(stderr, "Bad parse: at leaf, could not find suitable parent to continue or return");
parser_error = TRUE;
g_ptr_array_free(termList, TRUE);
g_ptr_array_free(parentsList, TRUE);
return FALSE;
/* error */
}
}
}
}
AST* getASTFromString(char* str, size_t len, int debug) {
int oldDebug = parser_DEBUG;
#ifdef NORMAL_GC
AST* root = (AST*)GC_debug_malloc(sizeof(AST), __FILE__, __LINE__);
#else
AST* root = (AST*)malloc(sizeof(AST));
#endif
memset(root, 0, sizeof(AST));
currentBuf = stringbuffer_new(str, len);
parser_DEBUG = debug;
parser_error = FALSE;
zzerr = parser_errorWriter;
zzmode(START);
ANTLRf(startOneOnly(&root), currentBuf_read);
stringbuffer_delete(currentBuf);
parser_DEBUG = oldDebug;
return root;
}
ICLTerm* parser_getTermFromString(char* str, size_t len) {
return parser_getTermFromStringReal(str, len, FALSE);
}
ICLTerm* parser_getTermFromStringDebug(char* str, size_t len) {
return parser_getTermFromStringReal(str, len, TRUE);
}
ICLTerm* parser_getTermFromStringReal(char* str, size_t len, int debug) {
AST* root = getASTFromString(str, len, debug);
AST* treeTerm = zzchild(root);
ICLTerm* result = NULL;
int parsedOkay = FALSE;
if(parser_error) {
parser_error = FALSE;
parser_freeTree(root);
zzfree_ast(root);
icl_Free(result);
return NULL;
}
parsedOkay = astToTerm(treeTerm, &result, debug);
if(parser_error) {
parser_error = FALSE;
parser_freeTree(root);
zzfree_ast(root);
icl_Free(result);
return NULL;
}
if(parsedOkay == TRUE) {
zzfree_ast(root);
return result;
}
else {
parser_freeTree(root);
zzfree_ast(root);
return NULL;
}
}
int parser_getNetTermFromBuf(ICLTerm** result, stringbuffer_t* buf) {
#ifdef NORMAL_GC
AST* root = (AST*)GC_debug_malloc(sizeof(AST), __FILE__, __LINE__);
#else
AST* root = (AST*)malloc(sizeof(AST));
#endif
int parsedOkay = FALSE;
*result = NULL;
memset(root, 0, sizeof(AST));
currentBuf = buf;
parser_error = FALSE;
zzerr = parser_errorWriter;
zzmode(START);
ANTLRf(startNet(&root), currentBuf_read);
if(parser_error) {
parser_freeTree(root);
zzfree_ast(root);
icl_Free(*result);
*result = NULL;
if(parser_DEBUG) {
printf("parser_getNetTermFromBuf parser_error\n");
}
return FALSE;
}
parsedOkay = astToTerm(zzchild(root), result, FALSE);
if(parser_error) {
parser_freeTree(root);
zzfree_ast(root);
icl_Free(*result);
*result = NULL;
if(parser_DEBUG) {
printf("parser_getNetTermFromBuf parser_error\n");
}
return FALSE;
}
if(parsedOkay == TRUE) {
zzfree_ast(root);
return TRUE;
}
else {
parser_freeTree(root);
zzfree_ast(root);
if(parser_DEBUG) {
printf("parser_getNetTermFromBuf didn't parse okay\n");
}
return FALSE;
}
}
/*
int main(int argc, char* argv[]) {
AST* root;
while(1) {
zzmode(START);
ANTLR(startNet(&root), stdin);
printf("Printing AST: \n");
zzpre_ast(zzchild(root), printAst, before, after);
}
}
*/
>>
#token GROUP
#token LIST
#token VAR
#token STRUCT
#token ICLDATAQ
#token STR
#token INT
#token FLOAT
#token TERM_LITERAL "term"
#token ICLDATAQ_LITERAL "icldataq"
#token LBRACE "\{"
#token RBRACE "\}"
#token LBRACK "\["
#token RBRACK "\]"
#token LPAREN "\("
#token RPAREN "\)"
#token DBL_COLON "::"
#token TURNSTILE ":\-"
#token COLON ":"
#token SEMI ";"
#token COMMA ","
//#token QUESTIONMARK "?"
#token PLUS "\+"
#token MINUS "\-"
#token STAR "\*"
#token DIV "/"
#token EQUAL "="
#token BACKSLASH "\\"
#token BANG "!"
#token TILDE "\~"
#token PIPE "\|"
#token DOT "\."
#token NUM_INTONE "{[\+\-]}[1-9][0-9]*"
#token NUM_INTTWO "{[\+\-]}0"
#token NUM_FLOATONE "{[\+\-]}([0-9]+.[0-9]* | [0-9]*.[0-9]+) {[eE]{[\-\+]}[0-9]+}"
#token NUM_FLOATTWO "{[\+\-]}[0-9]+ [eE]{[\-\+]}[0-9]+"
#token WS "[\t\ ]+" << zzskip (); >>
#token NEWLINE "(\n\r) | \n | \r" << ++zzline; zzskip(); >>
//#token SPECIAL_CHAR_LITERAL "((\* | \/ | \+ | \- | :\- | :: | = | \\)[\+\-\*\^\<\>\=\`\:\.\?\@\#\$\&\/\\]+ | [\^\<\>\`\:\?\@\#\$\&][\+\-\*\^\<\>\=\`\:\.\?\@\#\$\&\/\\]*)"
#token SPECIAL_CHAR_LITERAL "((\* | \/ | \+ | \- | :\- | :: | = | \\)[\+\-\*\^\<\>\=\`\:\.\?\@\#\$\&\/\\]+ | [\^\<\>\`\:\?\@\#\$\&][\+\-\*\^\<\>\=\`\:\.\?\@\#\$\&\/\\]*)"
#token IDENT "[a-z][a-zA-Z0-9_]*"
#token VARIABLE "[A-Z_][a-zA-Z0-9_]*"
#token "'" << zzmode (STRING_LITERAL_CLASS); zzmore(); >>
/* Note the bit of trickery here--we call handleDblQuotedData to skip the */
/* automaton from handling most of this token--handleDblQuotedData will rewind */
/* the currentBuf to the ending double quote before returning so that the */
/* automaton will continue correctly */
#token "\"" << parser_dblQuoteLen = 0; zzreplstr(""); zzmode (DBLQUOTED_CLASS); handleDblQuotedData(); zzmore(); >>
#lexclass STRING_LITERAL_CLASS
#token "''" << zzmore(); >>
#token STRING_LITERAL "'" << zzmode(START); >>
#token "[\n\r]" << ++zzline; zzmore(); >>
#token "~['\n\r]+" << zzmore(); >>
#lexclass DBLQUOTED_CLASS
#token DBLQUOTED "\"" << zzreplstr(""); zzmode(START); >>
/*#token "\"\"" << ++parser_dblQuoteLen; zzreplchar('"'); zzmore();>>
#token "~[\"]" << ++parser_dblQuoteLen; zzmore(); >>
#token "[\0x00-\0x41] | [\0x43-\0xff]" << ++parser_dblQuoteLen; zzmore(); >>
#token "[\n\r]" << ++parser_dblQuoteLen; ++zzline; zzmore(); >>
#token "([\0x00-\0xFF] | [\b])+" << ++parser_dblQuoteLen; zzmore(); >>
#token "~[\"\n\r]+" << ++parser_dblQuoteLen; zzmore(); >>
#token "([\0000-\0011] | [\0013-\0014] | [\0016-\0041] | [\0043-\0177])+" << zzmore(); >>*/
#lexclass START
startOneOnly
:
structure {DOT!} << if(parser_DEBUG) printf("completed structure for startOneOnly\n"); >>
;
startNet
:
{DOT!} netstruct << if(parser_DEBUG) printf("completed netstruct for startNet\n"); >>
;
netstruct
:
TERM_LITERAL^<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("netstruct\n"); >>
LPAREN!
nonEmptyExpressionList
RPAREN! << zzEXIT(zztasp1); return; >>
;
structure
:
semiExpression ((TURNSTILE^)<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("struct\n");>> semiExpression)*
;
semiExpression
:
backslashExpression ((SEMI^)<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("semiExpression\n");>> backslashExpression)*
;
backslashExpression
:
equalsExpression ((BACKSLASH^)<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("backslashExpression\n");>> equalsExpression)*
;
equalsExpression
:
colonExpression ((EQUAL^)<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("equalsExpression\n");>> colonExpression)*
;
colonExpression
:
plusMinusExpression (( COLON^ | DBL_COLON^)<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("colonExpr\n"); >> plusMinusExpression)*
;
plusMinusExpression
:
multiplicativeExpression (( PLUS^ | MINUS^ )<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("plusMinusExpression\n"); >> multiplicativeExpression)*
;
multiplicativeExpression
:
unaryExpression (( STAR^ | DIV^ )<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("multiplicativeExpr\n"); >> unaryExpression)*
;
unaryExpression
:
normalStruct
| icldataqStruct
| unaryExpressionNotPlusMinus
;
normalStruct
:
(BANG^ | SEMI^ | STRING_LITERAL^ | IDENT^ | PLUS^ | MINUS^ | STAR^ | DIV^ | EQUAL^ | TURNSTILE^ | COLON^ | DBL_COLON^ | SPECIAL_CHAR_LITERAL^ | BACKSLASH^)<< (*_root)->type = STRUCT; if(parser_DEBUG) printf("normalStruct\n"); >>
LPAREN!
nonEmptyExpressionList
RPAREN!
;
nonEmptyExpressionList
:
structure
(COMMA!
structure
)*
;
expressionList
:
( structure
(COMMA!
structure
)*
|
)
;
icldataqStruct
:
ICLDATAQ_LITERAL!
LPAREN!
(icldataqShortStruct | icldataqLongStruct)
RPAREN!
;
icldataqShortStruct
:
DBLQUOTED^<< (*_root)->type = ICLDATAQ; if(parser_DEBUG) printf("icldataqShort\n"); >>
;
icldataqLongStruct
:
(NUM_INTONE! | NUM_INTTWO!) COMMA! (NUM_INTONE! | NUM_INTTWO!) COMMA! DBLQUOTED^<< (*_root)->type = ICLDATAQ; if(parser_DEBUG) printf("icldataqLong\n"); >>
;
unaryExpressionNotPlusMinus
:
NUM_INTONE<<(*_root)->type = INT; if(parser_DEBUG) printf("intone\n"); >>
| NUM_INTTWO<<(*_root)->type = INT; if(parser_DEBUG) printf("inttwo\n"); >>
| NUM_FLOATONE<<(*_root)->type = FLOAT; if(parser_DEBUG) printf("floatone\n"); >>
| NUM_FLOATTWO<<(*_root)->type = FLOAT; if(parser_DEBUG) printf("floattwo\n"); >>
| str
| var
| list
| group
;
str
:
BANG<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| SEMI<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| STRING_LITERAL<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| STAR<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| PLUS<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| MINUS<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| DIV<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| EQUAL<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| TURNSTILE<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| IDENT<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| SPECIAL_CHAR_LITERAL<<(*_root)->type = STR; if(parser_DEBUG) printf("SPECIAL_CHAR_LITERAL str\n"); printf("%s\n", (*_root)->tokenData); >>
| TERM_LITERAL<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
| ICLDATAQ_LITERAL<<(*_root)->type = STR; if(parser_DEBUG) printf("str\n"); >>
;
var
:
VARIABLE<<(*_root)->type = VAR; if(parser_DEBUG) printf("var\n"); >>
;
list
:
LBRACK^<<(*_root)->type = LIST; if(parser_DEBUG) printf("list\n"); >>
expressionList
RBRACK!
;
group
:
LBRACE^<<(*_root)->type = GROUP; if(parser_DEBUG) printf("group\n"); >>
expressionList
RBRACE!
|
LPAREN^<<(*_root)->type = GROUP; if(parser_DEBUG) printf("group\n"); >>
expressionList
RPAREN!
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -