void CompilationEngine::compileClassVarDec() { /* ('static' | 'field') type varName (',' varName)* ';' */ tagNonTerminal("classVarDec"); if (jt.keyword() == Keyword::kFIELD) readKeyword("field", Keyword::kFIELD); else readKeyword("static", Keyword::kSTATIC); nextToken(); readType(); nextToken(); readIdentifier(); nextToken(); while (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == ',') { readSymbol(','); nextToken(); readIdentifier(); nextToken(); } readSymbol(';'); untagNonTerminal("classVarDec"); nextToken(); }
void CompilationEngine::compileSubroutineCall(string subName) { /* subroutineName '(' expressionList ')' | (className | varName) '.' subroutineName '(' expression ')' */ string oldTok = jt.getToken(); jt.setToken(subName); readIdentifier(); jt.setToken(oldTok); if (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == '(') { readSymbol('('); nextToken(); compileExpressionList(); readSymbol(')'); } else { readSymbol('.'); nextToken(); readIdentifier(); nextToken(); readSymbol('('); nextToken(); compileExpressionList(); readSymbol(')'); } nextToken(); }
void CompilationEngine::compileParameterList() { /* ((type varName)(',' type varName)*)? */ tagNonTerminal("parameterList"); if (jt.tokenType() != TokenType::kSYMBOL) { readType(); nextToken(); readIdentifier(); nextToken(); while (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == ',') { readSymbol(','); nextToken(); readType(); nextToken(); readIdentifier(); nextToken(); } } untagNonTerminal("parameterList"); }
static void findSchemeTags (void) { vString *name = vStringNew (); const unsigned char *line; while ((line = readLineFromInputFile ()) != NULL) { const unsigned char *cp = line; if (cp [0] == '(' && (cp [1] == 'D' || cp [1] == 'd') && (cp [2] == 'E' || cp [2] == 'e') && (cp [3] == 'F' || cp [3] == 'f')) { while (*cp != '\0' && !isspace (*cp)) cp++; /* Skip over open parens and white space */ do { while (*cp != '\0' && (isspace (*cp) || *cp == '(')) cp++; if (*cp == '\0') cp = line = readLineFromInputFile (); else break; } while (line); if (line == NULL) break; readIdentifier (name, cp); makeSimpleTag (name, SchemeKinds, K_FUNCTION); } if (cp [0] == '(' && (cp [1] == 'S' || cp [1] == 's') && (cp [2] == 'E' || cp [2] == 'e') && (cp [3] == 'T' || cp [3] == 't') && (cp [4] == '!') && (isspace (cp [5]) || cp[5] == '\0')) { cp += 5; /* Skip over white space */ do { while (*cp != '\0' && isspace (*cp)) cp++; if (*cp == '\0') cp = line = readLineFromInputFile (); else break; } while (line); if (line == NULL) break; readIdentifier (name, cp); makeSimpleTag (name, SchemeKinds, K_SET); } } vStringDelete (name); }
static int directiveDefine (const int c, bool undef) { int r = CORK_NIL; if (cppIsident1 (c)) { bool parameterized; int nc; readIdentifier (c, Cpp.directive.name); nc = getcAndCollect (); parameterized = (nc == '('); if (parameterized) { cppStartCollectingSignature (); while (nc != EOF) { int lastC = nc; nc = getcAndCollect (); if (nc == '\n' && lastC != '\\') break; } cppStopCollectingSignature (); } ungetcAndCollect (nc); if (! isIgnore ()) makeDefineTag (vStringValue (Cpp.directive.name), parameterized, undef); } Cpp.directive.state = DRCTV_NONE; return r; }
void CompilationEngine::readType() { if (jt.tokenType() == TokenType::kKEYWORD) { switch (jt.keyword()) { case Keyword::kINT: readKeyword("int", Keyword::kINT); break; case Keyword::kCHAR: readKeyword("char", Keyword::kCHAR); break; case Keyword::kBOOLEAN: readKeyword("boolean", Keyword::kBOOLEAN); break; default: break; } } else { readIdentifier(); } }
void CompilationEngine::compileClass() { /* 'class' className '{' classVarDec* subroutineDec* '}' */ tagNonTerminal("class"); nextToken(); readKeyword("class", Keyword::kCLASS); nextToken(); readIdentifier(); nextToken(); readSymbol('{'); nextToken(); while (jt.tokenType() == TokenType::kKEYWORD && (jt.keyword() == Keyword::kFIELD || jt.keyword() == Keyword::kSTATIC)) compileClassVarDec(); while (jt.tokenType() == TokenType::kKEYWORD && (jt.keyword() == Keyword::kCONSTRUCTOR || jt.keyword() == Keyword::kFUNCTION || jt.keyword() == Keyword::kMETHOD)) compileSubroutine(); readSymbol('}'); untagNonTerminal("class"); if (jt.advance()) // jack language does not allow anything else beyond the class throw CompilationException("jack language does not allow anything else beyond the class"); }
void CompilationEngine::compileLet() { /*'let' varName('[' expression ']')? '=' expression ';' */ tagNonTerminal("letStatement"); readKeyword("let", Keyword::kLET); nextToken(); readIdentifier(); nextToken(); if (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == '[') { readSymbol('['); nextToken(); compileExpression(); readSymbol(']'); nextToken(); } readSymbol('='); nextToken(); compileExpression(); readSymbol(';'); untagNonTerminal("letStatement"); nextToken(); }
static void findVerilogTags (void) { vString *const name = vStringNew (); volatile bool newStatement = true; volatile int c = '\0'; exception_t exception = (exception_t) setjmp (Exception); if (exception == ExceptionNone) while (c != EOF) { c = vGetc (); switch (c) { case ';': case '\n': newStatement = true; break; case ' ': case '\t': break; default: if (newStatement && readIdentifier (name, c)) findTag (name); newStatement = false; break; } } vStringDelete (name); }
void CompilationEngine::compileSubroutine() { /* ('constructor' | 'function' | 'method') ('void' | type) subroutineName '(' parameterList ')' subroutineBody */ tagNonTerminal("subroutineDec"); if (jt.keyword() == Keyword::kCONSTRUCTOR) readKeyword("constructor", Keyword::kCONSTRUCTOR); else if (jt.keyword() == Keyword::kFUNCTION) readKeyword("function", Keyword::kFUNCTION); else readKeyword("method", Keyword::kMETHOD); nextToken(); if (jt.tokenType() == TokenType::kKEYWORD && jt.keyword() == Keyword::kVOID) readKeyword("void", Keyword::kVOID); else readType(); nextToken(); readIdentifier(); nextToken(); readSymbol('('); nextToken(); compileParameterList(); readSymbol(')'); nextToken(); compileSubroutineBody(); untagNonTerminal("subroutineDec"); }
static void processTypedef (tokenInfo *const token) { /*Note: At the moment, only identifies typedef name and not its contents */ int c; /* Get identifiers */ c = skipWhite (vGetc ()); while (isIdentifierCharacter (c)) { readIdentifier (token, c); c = skipWhite (vGetc ()); } /* Skip bus width definition */ if (c == '[') { skipPastMatch ("[]"); c = skipWhite (vGetc ()); } /* Skip typedef contents */ if (c == '{') { skipPastMatch ("{}"); c = skipWhite (vGetc ()); } /* Skip past class parameter override */ if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') { skipPastMatch ("()"); } c = skipWhite (vGetc ()); } /* Read new typedef identifier */ if (isIdentifierCharacter (c)) { readIdentifier (token, c); } /* Use last identifier to create tag */ createTag (token); }
QString NSParser::readVar(Symbol* symbol) { QString varName; Symbol* identifier = searchChild(symbol, SYM_IDENTIFIER); if (identifier) varName = readIdentifier(identifier); return varName; }
static void tagNameList (const vhdlKind kind, int c) { Assert (isIdentifierCharacter (c)); if (isIdentifierCharacter (c)) { readIdentifier (TagName, c); makeSimpleTag (TagName, VhdlKinds, kind); } }
static void findVerilogTags (void) { tokenInfo *const token = newToken (); int c = '\0'; currentContext = newToken (); while (c != EOF) { c = vGetc (); c = skipWhite (c); switch (c) { /* Store current block name whenever a : is found * This is used later by any tag type that requires this information * */ case ':': vStringCopy (currentContext->blockName, token->name); break; /* Skip interface modport port declarations */ case '(': if (currentContext && currentContext->lastKind == K_MODPORT) { skipPastMatch ("()"); } break; /* Drop context on prototypes because they don't have an end * statement */ case ';': if (currentContext->scope && currentContext->scope->prototype) { verbose ("Dropping context %s\n", vStringValue (currentContext->name)); currentContext = popToken (currentContext); currentContext->prototype = FALSE; } /* Prototypes end at the end of statement */ if (currentContext->prototype) { currentContext->prototype = FALSE; } break; default : if (isIdentifierCharacter (c)) { readIdentifier (token, c); updateKind (token); findTag (token); } } } deleteToken (token); pruneTokens (currentContext); currentContext = NULL; }
static void findTag (vString *const name) { int c = '\0'; vhdlKind kind; vStringCopyToLower (Keyword, name); kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl); if (kind == K_UNDEFINED) { c = skipWhite (vGetc ()); vStringCopyS(Lastname,vStringValue(name)); if (c == ':') { c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (name, c); vStringCopyToLower (Keyword, name); lookupKeyword (vStringValue (Keyword), Lang_vhdl); kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl); if (kind == K_PROCESS || kind == K_BLOCK || kind == K_PORT) { makeSimpleTag (Lastname, VhdlKinds, kind); } } } else { vUngetc (c); } } else { if (kind == K_SIGNAL) { while (c!=':') { c = skipWhite (vGetc ()); if (c==',') c = vGetc (); if (isIdentifierCharacter (c)) tagNameList (kind, c); else break; c = vGetc (); } } else if (kind == K_PROCESS || kind == K_BLOCK) { vStringCopyS(TagName,"unnamed"); makeSimpleTag (TagName, VhdlKinds, kind); } else { c = skipWhite (vGetc ()); if (c=='\"') c = vGetc (); if (isIdentifierCharacter (c)) tagNameList (kind, c); } } }
static void directivePragma (int c) { if (cppIsident1 (c)) { readIdentifier (c, Cpp.directive.name); if (stringMatch (vStringValue (Cpp.directive.name), "weak")) { /* generate macro tag for weak name */ do { c = getcAndCollect (); } while (c == SPACE); if (cppIsident1 (c)) { readIdentifier (c, Cpp.directive.name); makeDefineTag (vStringValue (Cpp.directive.name), NULL, false); } } } Cpp.directive.state = DRCTV_NONE; }
void CompilationEngine::compileVarDec() { /* 'var' type varName (',' varName)* ';' */ tagNonTerminal("varDec"); readKeyword("var", Keyword::kVAR); nextToken(); readType(); nextToken(); readIdentifier(); nextToken(); while (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == ',') { readSymbol(','); nextToken(); readIdentifier(); nextToken(); } readSymbol(';'); untagNonTerminal("varDec"); nextToken(); }
static int skipMacro (int c) { tokenInfo *token = newToken ();; if (c == '`') { /* Skip keyword */ if (isIdentifierCharacter (c = vGetc ())) { readIdentifier (token, c); c = vGetc (); /* Skip next keyword if macro is `ifdef or `ifndef or `elsif*/ if (strcmp (vStringValue (token->name), "ifdef") == 0 || strcmp (vStringValue (token->name), "ifndef") == 0 || strcmp (vStringValue (token->name), "elsif") == 0) { verbose ("%c\n", c); c = skipWhite (c); readIdentifier (token, c); c = vGetc (); verbose ("Skipping conditional macro %s\n", vStringValue (token->name)); } /* Skip macro functions */ else { c = skipWhite (c); if (c == '(') { c = skipPastMatch ("()"); } } } } deleteToken (token); return c; }
static boolean findBlockName (tokenInfo *const token) { int c; c = skipWhite (vGetc ()); if (c == ':') { c = skipWhite (vGetc ()); readIdentifier (token, c); return (boolean) (vStringLength (token->name) > 0); } else vUngetc (c); return FALSE; }
static void processFunction (tokenInfo *const token) { int c; tokenInfo *classType; /* Search for function name * Last identifier found before a '(' or a ';' is the function name */ c = skipWhite (vGetc ()); do { readIdentifier (token, c); c = skipWhite (vGetc ()); /* Identify class type prefixes and create respective context*/ if (isLanguage (Lang_systemverilog) && c == ':') { c = vGetc (); if (c == ':') { verbose ("Found function declaration with class type %s\n", vStringValue (token->name)); classType = newToken (); vStringCopy (classType->name, token->name); classType->kind = K_CLASS; createContext (classType); currentContext->classScope = TRUE; } else { vUngetc (c); } } } while (c != '(' && c != ';' && c != EOF); if ( vStringLength (token->name) > 0 ) { verbose ("Found function: %s\n", vStringValue (token->name)); /* Create tag */ createTag (token); /* Get port list from function */ processPortList (c); } }
static void tagNameList (const verilogKind kind, int c) { vString *name = vStringNew (); bool repeat; Assert (isIdentifierCharacter (c)); do { repeat = false; if (isIdentifierCharacter (c)) { readIdentifier (name, c); makeSimpleTag (name, VerilogKinds, kind); } else break; c = skipWhite (vGetc ()); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '=') { c = skipWhite (vGetc ()); if (c == '{') skipPastMatch ("{}"); else { do c = vGetc (); while (c != ',' && c != ';'); } } if (c == ',') { c = skipWhite (vGetc ()); repeat = true; } else repeat = false; } while (repeat); vStringDelete (name); vUngetc (c); }
static void findTag (vString *const name) { const verilogKind kind = (verilogKind) lookupKeyword (vStringValue (name), Lang_verilog); if (kind == K_CONSTANT && vStringItem (name, 0) == '`') { /* Bug #961001: Verilog compiler directives are line-based. */ int c = skipWhite (vGetc ()); readIdentifier (name, c); makeSimpleTag (name, VerilogKinds, kind); /* Skip the rest of the line. */ do { c = vGetc(); } while (c != '\n'); vUngetc (c); } else if (kind != K_UNDEFINED) { int c = skipWhite (vGetc ()); /* Many keywords can have bit width. * reg [3:0] net_name; * inout [(`DBUSWIDTH-1):0] databus; */ if (c == '(') c = skipPastMatch ("()"); c = skipWhite (c); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '#') { c = vGetc (); if (c == '(') c = skipPastMatch ("()"); } c = skipWhite (c); if (isIdentifierCharacter (c)) tagNameList (kind, c); } }
static void findVhdlTags (void) { volatile boolean newStatement = TRUE; volatile int c = '\0'; exception_t exception = (exception_t) setjmp (Exception); Name = vStringNew (); Lastname = vStringNew (); Keyword = vStringNew (); TagName = vStringNew (); if (exception == ExceptionNone) while (c != EOF) { c = vGetc (); switch (c) { case ';': case '\n': newStatement = TRUE; break; case ' ': case '\t': break; default: if (newStatement && readIdentifier (Name, c)) { findTag (Name); } newStatement = FALSE; break; } } vStringDelete (Name); vStringDelete (Lastname); vStringDelete (Keyword); vStringDelete (TagName); }
static void processFunction (tokenInfo *const token) { int c; /* Search for function name * Last identifier found before a '(' or a ';' is the function name */ c = skipWhite (vGetc ()); do { readIdentifier (token, c); c = skipWhite (vGetc ()); } while (c != '(' && c != ';' && c != EOF); if ( vStringLength (token->name) > 0 ) { verbose ("Found function: %s\n", vStringValue (token->name)); /* Create tag */ createTag (token); /* Get port list from function */ processPortList (c); } }
static void findMakeTags (void) { stringList *identifiers = stringListNew (); boolean newline = TRUE; boolean in_define = FALSE; boolean in_rule = FALSE; boolean variable_possible = TRUE; int c; while ((c = nextChar ()) != EOF) { if (newline) { if (in_rule) { if (c == '\t' || (c = skipToNonWhite (c)) == '#') { skipLine (); /* skip rule or comment */ c = nextChar (); } else if (c != '\n') in_rule = FALSE; } stringListClear (identifiers); variable_possible = (boolean)(!in_rule); newline = FALSE; } if (c == '\n') newline = TRUE; else if (isspace (c)) continue; else if (c == '#') skipLine (); else if (variable_possible && c == '?') { c = nextChar (); ungetcToInputFile (c); variable_possible = (c == '='); } else if (variable_possible && c == ':' && stringListCount (identifiers) > 0) { c = nextChar (); ungetcToInputFile (c); if (c != '=') { unsigned int i; for (i = 0; i < stringListCount (identifiers); i++) newTarget (stringListItem (identifiers, i)); stringListClear (identifiers); in_rule = TRUE; } } else if (variable_possible && c == '=' && stringListCount (identifiers) == 1) { newMacro (stringListItem (identifiers, 0)); skipLine (); in_rule = FALSE; } else if (variable_possible && isIdentifier (c)) { vString *name = vStringNew (); readIdentifier (c, name); stringListAdd (identifiers, name); if (stringListCount (identifiers) == 1) { if (in_define && ! strcmp (vStringValue (name), "endef")) in_define = FALSE; else if (in_define) skipLine (); else if (! strcmp (vStringValue (name), "define")) { in_define = TRUE; c = skipToNonWhite (nextChar ()); vStringClear (name); /* all remaining characters on the line are the name -- even spaces */ while (c != EOF && c != '\n') { vStringPut (name, c); c = nextChar (); } if (c == '\n') ungetcToInputFile (c); vStringTerminate (name); vStringStripTrailing (name); newMacro (name); } else if (! strcmp (vStringValue (name), "export")) stringListClear (identifiers); else if (! strcmp (vStringValue (name), "include") || ! strcmp (vStringValue (name), "sinclude") || ! strcmp (vStringValue (name), "-include")) { boolean optional = (vStringValue (name)[0] == 'i')? FALSE: TRUE; while (1) { c = skipToNonWhite (nextChar ()); readIdentifier (c, name); vStringStripTrailing (name); if (isAcceptableAsInclude(name)) newInclude (name, optional); /* non-space characters after readIdentifier() may * be rejected by the function: * e.g. * include $* * * Here, remove such characters from input stream. */ do c = nextChar (); while (c != EOF && c != '\n' && (!isspace (c))); if (c == '\n') ungetcToInputFile (c); if (c == EOF || c == '\n') break; } } } } else variable_possible = FALSE; } stringListDelete (identifiers); }
/* The lexer is in charge of reading the file. * Some of sub-lexer (like eatComment) also read file. * lexing is finished when the lexer return Tok_EOF */ static objcKeyword lex (lexingState * st) { int retType; /* handling data input here */ while (st->cp == NULL || st->cp[0] == '\0') { st->cp = readLineFromInputFile (); if (st->cp == NULL) return Tok_EOF; return Tok_EOL; } if (isAlpha (*st->cp) || (*st->cp == '_')) { readIdentifier (st); retType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC); if (retType == -1) /* If it's not a keyword */ { return ObjcIDENTIFIER; } else { return retType; } } else if (*st->cp == '@') { readIdentifierObjcDirective (st); retType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC); if (retType == -1) /* If it's not a keyword */ { return Tok_any; } else { return retType; } } else if (isSpace (*st->cp)) { eatWhiteSpace (st); return lex (st); } else switch (*st->cp) { case '(': st->cp++; return Tok_PARL; case '\\': st->cp++; return Tok_Backslash; case '#': st->cp++; return Tok_Sharp; case '/': if (st->cp[1] == '*') /* ergl, a comment */ { eatComment (st); return lex (st); } else if (st->cp[1] == '/') { st->cp = NULL; return lex (st); } else { st->cp++; return Tok_any; } break; case ')': st->cp++; return Tok_PARR; case '{': st->cp++; return Tok_CurlL; case '}': st->cp++; return Tok_CurlR; case '[': st->cp++; return Tok_SQUAREL; case ']': st->cp++; return Tok_SQUARER; case ',': st->cp++; return Tok_COMA; case ';': st->cp++; return Tok_semi; case ':': st->cp++; return Tok_dpoint; case '"': eatString (st); return Tok_any; case '+': st->cp++; return Tok_PLUS; case '-': st->cp++; return Tok_MINUS; case '*': st->cp++; return Tok_Asterisk; case '<': st->cp++; return Tok_ANGLEL; case '>': st->cp++; return Tok_ANGLER; default: st->cp++; break; } /* default return if nothing is recognized, * shouldn't happen, but at least, it will * be handled without destroying the parsing. */ return Tok_any; }
static void findMakeTags (void) { stringList *identifiers = stringListNew (); boolean newline = TRUE; boolean in_define = FALSE; boolean in_rule = FALSE; boolean variable_possible = TRUE; int c; while ((c = nextChar ()) != EOF) { if (newline) { if (in_rule) { if (c == '\t' || (c = skipToNonWhite (c)) == '#') { skipLine (); /* skip rule or comment */ c = nextChar (); } else if (c != '\n') in_rule = FALSE; } stringListClear (identifiers); variable_possible = (boolean)(!in_rule); newline = FALSE; } if (c == '\n') newline = TRUE; else if (isspace (c)) continue; else if (c == '#') skipLine (); else if (variable_possible && c == '?') { c = nextChar (); fileUngetc (c); variable_possible = (c == '='); } else if (variable_possible && c == ':' && stringListCount (identifiers) > 0) { c = nextChar (); fileUngetc (c); if (c != '=') { unsigned int i; for (i = 0; i < stringListCount (identifiers); i++) newTarget (stringListItem (identifiers, i)); stringListClear (identifiers); in_rule = TRUE; } } else if (variable_possible && c == '=' && stringListCount (identifiers) == 1) { newMacro (stringListItem (identifiers, 0)); skipLine (); in_rule = FALSE; } else if (variable_possible && isIdentifier (c)) { vString *name = vStringNew (); readIdentifier (c, name); stringListAdd (identifiers, name); if (stringListCount (identifiers) == 1) { if (in_define && ! strcmp (vStringValue (name), "endef")) in_define = FALSE; else if (in_define) skipLine (); else if (! strcmp (vStringValue (name), "define")) { in_define = TRUE; c = skipToNonWhite (nextChar ()); vStringClear (name); /* all remaining characters on the line are the name -- even spaces */ while (c != EOF && c != '\n') { vStringPut (name, c); c = nextChar (); } if (c == '\n') fileUngetc (c); vStringTerminate (name); vStringStripTrailing (name); newMacro (name); } else if (! strcmp (vStringValue (name), "export")) stringListClear (identifiers); } } else variable_possible = FALSE; } stringListDelete (identifiers); }
bool ClParserParser:: parse() { ClParserOperatorType op = CL_PARSER_OP_NONE; error_code_ = 0; bool expression = false; parse_.skipSpace(); while (! parse_.eof()) { /* <expression> := <inline_operator> <expression> <expression> := <expression> <inline_operator> */ if (parse_.isString("++") || parse_.isString("--")) { if (parse_.isChar('+')) ClParserStackMgrInst->push(CL_PARSER_OP_INCREMENT); else ClParserStackMgrInst->push(CL_PARSER_OP_DECREMENT); ClParserStackMgrInst->toNext(); parse_.skipChars(2); if (! expression) { ClParserParser parser(this); if (! parser.parse()) { error_code_ = parser.getErrorCode(); goto fail; } if (parser.isAssign()) { error_code_ = int(ClErr::INVALID_LVALUE_FOR_ASSIGNMENT); goto fail; } } expression = true; } /* <expression> := <unary_operator> <expression> */ else if (! expression && parse_.isOneOf(parser_unary_operator_chars)) { if (! readUnaryOperator(&op)) { error_code_ = int(ClErr::INVALID_CHARACTER); goto fail; } ClParserStackMgrInst->push(op); ClParserStackMgrInst->toNext(); ClParserParser parser(this); if (! parser.parse()) { error_code_ = parser.getErrorCode(); goto fail; } if (parser.isAssign()) { error_code_ = int(ClErr::INVALID_LVALUE_FOR_ASSIGNMENT); goto fail; } expression = true; } /* <expression> := '(' <expression> ')' */ else if (! expression && parse_.isChar('(')) { ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_R_BRACKET); ClParserStackMgrInst->toNext(); parse_.skipChar(); ClParserParser parser(this); /* TODO: set end char */ if (! parser.parse() && parser.getErrorCode() != int(ClErr::INVALID_CHARACTER)) { error_code_ = parser.getErrorCode(); goto fail; } parse_.skipSpace(); if (! parse_.isChar(')')) { error_code_ = int(ClErr::MISSING_CLOSE_ROUND_BRACKET); goto fail; } ClParserStackMgrInst->push(CL_PARSER_OP_CLOSE_R_BRACKET); ClParserStackMgrInst->toNext(); parse_.skipChar(); expression = true; } /* <expression> := <numeric_value> */ else if (! expression && (parse_.isDigit() || parse_.isChar('.'))) { ClParserValuePtr value; if (! readNumericValue(value)) goto fail; ClParserStackMgrInst->push(value); ClParserStackMgrInst->toNext(); expression = true; } /* <expression> := <string_value> */ else if (! expression && parse_.isOneOf(parser_string_chars)) { ClParserValuePtr value; if (! readStringValue(value)) goto fail; ClParserStackMgrInst->push(value); ClParserStackMgrInst->toNext(); expression = true; } /* <expression> := <array_value> */ else if (! expression && parse_.isChar('[')) { ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_S_BRACKET); ClParserStackMgrInst->toNext(); parse_.skipChar(); if (! readArray()) goto fail; expression = true; } /* <expression> := <dict_value> */ else if (! expression && parse_.isString("{{")) { ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_DICT); ClParserStackMgrInst->toNext(); parse_.skipChars(2); if (! readDictionary()) goto fail; expression = true; } /* <expression> := <list_value> */ else if (! expression && parse_.isChar('{')) { ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_BRACE); ClParserStackMgrInst->toNext(); parse_.skipChar(); if (! readList()) goto fail; expression = true; } /* <expression> := <expression> <binary_operator> <expression> */ else if (expression && parse_.isOneOf(parser_binary_operator_chars)) { if (! readBinaryOperator(&op)) goto fail; ClParserStackMgrInst->push(op); ClParserStackMgrInst->toNext(); ClParserParser parser(this); if (! parser.parse()) { error_code_ = parser.getErrorCode(); goto fail; } ClParserOperatorPtr op1 = ClParserOperatorMgrInst->getOperator(op); if (! op1->isAssignment() && parser.isAssign()) { error_code_ = int(ClErr::INVALID_LVALUE_FOR_ASSIGNMENT); goto fail; } if (op1->isAssignment()) assign_ = true; expression = true; } /* <expression> := <expression> '?' <expression> ':' <expression> */ else if (expression && parse_.isChar('?')) { ClParserStackMgrInst->push(CL_PARSER_OP_QUESTION_MARK); ClParserStackMgrInst->toNext(); parse_.skipChar(); ClParserParser parser1(this); if (! parser1.parse() && parser1.getErrorCode() != int(ClErr::INVALID_CHARACTER)) { error_code_ = parser1.getErrorCode(); goto fail; } parse_.skipSpace(); if (! parse_.isChar(':')) { error_code_ = int(ClErr::MISSING_COLON_OPERATOR); goto fail; } ClParserStackMgrInst->push(CL_PARSER_OP_COLON); ClParserStackMgrInst->toNext(); parse_.skipChar(); ClParserParser parser2(this); if (! parser2.parse() && parser2.getErrorCode() != int(ClErr::INVALID_CHARACTER)) { error_code_ = parser2.getErrorCode(); goto fail; } assign_ = parser1.isAssign() | parser2.isAssign(); expression = true; } /* <expression> := <expression> '[' <expression> ',' .... ']' */ else if (expression && parse_.isChar('[')) { ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_S_BRACKET); ClParserStackMgrInst->toNext(); parse_.skipChar(); if (! readArray()) goto fail; expression = true; } /* <expression> := <expression> ',' <expression> */ else if (expression && parse_.isChar(',')) { ClParserStackMgrInst->push(CL_PARSER_OP_COMMA); ClParserStackMgrInst->toNext(); parse_.skipChar(); ClParserParser parser(this); if (! parser.parse()) { error_code_ = parser.getErrorCode(); goto fail; } expression = true; } /* <expression> := <variable> */ /* <expression> := <variable> '.' <variable> '.' <...> */ /* <expression> := <variable> '[' <expression> ',' .... ']' */ /* <expression> := <function> '(' <expression> ',' .... ')' */ /* <expression> := <type> '(' <expression> ',' .... ')' */ else if (! expression && ((! ClParserInst->getDollarPrefix() && parse_.isIdentifier()) || ( ClParserInst->getDollarPrefix() && parse_.isChar('$') && parse_.isIdentifier(1)))) { if (ClParserInst->getDollarPrefix() && parse_.isChar('$')) parse_.skipChar(); ClParserIdentifierPtr identifier; if (! readIdentifier(identifier)) goto fail; const std::string &name = identifier->getName(); ClParserScopePtr scope = identifier->getScope(); parse_.skipSpace(); if (parse_.isChar('(')) { ClParserInternFnPtr internfn; if (scope.isValid()) internfn = scope->getInternFn(name); else internfn = ClParserInst->getInternFn(name); if (internfn.isValid()) { ClParserStackMgrInst->push(internfn); ClParserStackMgrInst->toNext(); } else { ClParserUserFnPtr userfn; if (scope.isValid()) userfn = scope->getUserFn(name); else userfn = ClParserInst->getUserFn(name); if (userfn.isValid()) { ClParserStackMgrInst->push(userfn); ClParserStackMgrInst->toNext(); } else { ClParserTypePtr type = ClParserInst->getType(name); if (type.isValid()) { ClParserStackMgrInst->push(type); ClParserStackMgrInst->toNext(); } else { identifier->setFunction(); ClParserStackMgrInst->push(identifier); ClParserStackMgrInst->toNext(); } } } ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_R_BRACKET); ClParserStackMgrInst->toNext(); parse_.skipChar(); if (! readArgList()) goto fail; expression = true; } else { identifier->setVariable(); ClParserStackMgrInst->push(identifier); ClParserStackMgrInst->toNext(); if (parse_.isChar('[')) { ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_S_BRACKET); ClParserStackMgrInst->toNext(); parse_.skipChar(); if (! readArray()) goto fail; parse_.skipSpace(); } while (parse_.isChar('.')) { identifier->setStructPart(); ClParserStackMgrInst->push(CL_PARSER_OP_DOT); ClParserStackMgrInst->toNext(); parse_.skipChar(); parse_.skipSpace(); if (! readIdentifier(identifier)) { error_code_ = int(ClErr::INVALID_CHARACTER); goto fail; } identifier->setVariable(); ClParserStackMgrInst->push(identifier); ClParserStackMgrInst->toNext(); if (parse_.isChar('[')) { ClParserStackMgrInst->push(CL_PARSER_OP_OPEN_S_BRACKET); ClParserStackMgrInst->toNext(); parse_.skipChar(); if (! readArray()) goto fail; parse_.skipSpace(); } } expression = true; } } /* <expression> := <string_value> */ else if (! expression && ClParserInst->getDollarPrefix()) { std::string str; parse_.readNonSpace(str); ClParserValuePtr value = ClParserValueMgrInst->createValue(str); ClParserStackMgrInst->push(value); ClParserStackMgrInst->toNext(); parse_.skipSpace(); expression = true; } else { error_code_ = int(ClErr::INVALID_CHARACTER); goto fail; } parse_.skipSpace(); } if (error_code_ == 0 && ! expression) { error_code_ = int(ClErr::NULL_EXPRESSION); goto fail; } if (parent_) parent_->parse_.setPos(parent_->parse_.getPos() + parse_.getPos()); return true; fail: if (parent_) parent_->parse_.setPos(parent_->parse_.getPos() + parse_.getPos()); return false; }
/* The lexer is in charge of reading the file. * Some of sub-lexer (like eatComment) also read file. * lexing is finished when the lexer return Tok_EOF */ static ocamlKeyword lex (lexingState * st) { int retType; /* handling data input here */ while (st->cp == NULL || st->cp[0] == '\0') { st->cp = fileReadLine (); if (st->cp == NULL) return Tok_EOF; } if (isAlpha (*st->cp)) { readIdentifier (st); retType = lookupKeyword (vStringValue (st->name), Lang_Ocaml); if (retType == -1) /* If it's not a keyword */ { return OcaIDENTIFIER; } else { return retType; } } else if (isNum (*st->cp)) return eatNumber (st); else if (isSpace (*st->cp)) { eatWhiteSpace (st); return lex (st); } /* OCaml permit the definition of our own operators * so here we check all the consecuting chars which * are operators to discard them. */ else if (isOperator[*st->cp]) return eatOperator (st); else switch (*st->cp) { case '(': if (st->cp[1] == '*') /* ergl, a comment */ { eatComment (st); return lex (st); } else { st->cp++; return Tok_PARL; } case ')': st->cp++; return Tok_PARR; case '[': st->cp++; return Tok_BRL; case ']': st->cp++; return Tok_BRR; case '{': st->cp++; return Tok_CurlL; case '}': st->cp++; return Tok_CurlR; case '\'': st->cp++; return Tok_Prime; case ',': st->cp++; return Tok_comma; case '=': st->cp++; return Tok_EQ; case ';': st->cp++; return Tok_semi; case '"': eatString (st); return Tok_Val; case '_': st->cp++; return Tok_Val; case '#': st->cp++; return Tok_Sharp; case '\\': st->cp++; return Tok_Backslash; default: st->cp++; break; } /* default return if nothing is recognized, * shouldn't happen, but at least, it will * be handled without destroying the parsing. */ return Tok_Val; }
static void findTag (tokenInfo *const token) { if (currentContext->kind != K_UNDEFINED) { /* Drop context, but only if an end token is found */ dropContext (token); } if (token->kind == K_CONSTANT && vStringItem (token->name, 0) == '`') { /* Bug #961001: Verilog compiler directives are line-based. */ int c = skipWhite (vGetc ()); readIdentifier (token, c); createTag (token); /* Skip the rest of the line. */ do { c = vGetc(); } while (c != EOF && c != '\n'); vUngetc (c); } else if (token->kind == K_BLOCK) { /* Process begin..end blocks */ processBlock (token); } else if (token->kind == K_FUNCTION || token->kind == K_TASK) { /* Functions are treated differently because they may also include the * type of the return value. * Tasks are treated in the same way, although not having a return * value.*/ processFunction (token); } else if (token->kind == K_ASSERTION) { if (vStringLength (currentContext->blockName) > 0) { vStringCopy (token->name, currentContext->blockName); createTag (token); skipToSemiColon (); } } else if (token->kind == K_TYPEDEF) { processTypedef (token); } else if (token->kind == K_CLASS) { processClass (token); } else if (token->kind == K_IGNORE && isSingleStatement (token)) { currentContext->singleStat = TRUE; } else if (isVariable (token)) { int c = skipWhite (vGetc ()); tagNameList (token, c); } else if (token->kind != K_UNDEFINED && token->kind != K_IGNORE) { int c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); while (getKind (token) == K_IGNORE) { c = skipWhite (vGetc ()); readIdentifier (token, c); } createTag (token); /* Get port list if required */ c = skipWhite (vGetc ()); if (c == '(' && hasSimplePortList (token)) { processPortList (c); } else { vUngetc (c); } } } }