mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
(fix) fix multi comment err on one line
This commit is contained in:
parent
1005ca64ef
commit
7e8241ab15
2
port/linux/.vscode/launch.json
vendored
2
port/linux/.vscode/launch.json
vendored
@ -12,7 +12,7 @@
|
||||
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
|
||||
"args": [
|
||||
// "--gtest_filter=pikaui.*"
|
||||
// "--gtest_filter=parser.for_in_split"
|
||||
"--gtest_filter=*.common_issue_1b23f4*"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
|
157
src/PikaParser.c
157
src/PikaParser.c
@ -1812,7 +1812,7 @@ static int32_t Parser_getPyLineBlockDeepth(char* line) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* Parser_removeAnnotation(char* line) {
|
||||
char* Parser_removeComment(char* line) {
|
||||
uint8_t is_annotation_exit = 0;
|
||||
uint8_t is_in_single_quotes = 0;
|
||||
uint8_t is_in_pika_float_quotes_deepth = 0;
|
||||
@ -2419,7 +2419,7 @@ static char* Suger_import(Args* outbuffs, char* line) {
|
||||
}
|
||||
|
||||
static char* Parser_linePreProcess(Args* outbuffs, char* line) {
|
||||
line = Parser_removeAnnotation(line);
|
||||
line = Parser_removeComment(line);
|
||||
Arg* line_buff = NULL;
|
||||
int line_num = 0;
|
||||
/* check syntex error */
|
||||
@ -2497,172 +2497,177 @@ static int Parser_isVoidLine(char* line) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t Parser_checkIsMultiComment(char* line) {
|
||||
for (uint32_t i = 0; i < strGetSize(line); i++) {
|
||||
static uint8_t Parser_checkIsMultiComment(char* line, uint8_t* pbIsOneLine) {
|
||||
uint8_t bIsMultiComment = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t uLineSize = strGetSize(line);
|
||||
while (i + 2 < uLineSize) {
|
||||
/* not match ' or " */
|
||||
if ((line[i] != '\'') && (line[i] != '"')) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
/* not match ''' or """ */
|
||||
if (!((line[i + 1] == line[i]) && (line[i + 2] == line[i]))) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
// /* check char befor the ''' or """ */
|
||||
// if (!((0 == i) || (line[i - 1] == ' '))) {
|
||||
// continue;
|
||||
// }
|
||||
// /* check char after the ''' or """ */
|
||||
// if (!((line[i + 3] == ' ') || (line[i + 3] == 0))) {
|
||||
// continue;
|
||||
// }
|
||||
/* mached */
|
||||
return 1;
|
||||
if (bIsMultiComment) {
|
||||
*pbIsOneLine = 1;
|
||||
}
|
||||
bIsMultiComment = 1;
|
||||
i += 3;
|
||||
}
|
||||
/* not mached */
|
||||
return 0;
|
||||
return bIsMultiComment;
|
||||
}
|
||||
|
||||
static char* _Parser_linesToBytesOrAsm(Args* outBuffs,
|
||||
ByteCodeFrame* bytecode_frame,
|
||||
char* py_lines) {
|
||||
Stack block_stack;
|
||||
stack_init(&block_stack);
|
||||
Arg* asm_buff = arg_newStr("");
|
||||
uint32_t lines_offset = 0;
|
||||
uint16_t lines_num = strCountSign(py_lines, '\n') + 1;
|
||||
uint16_t lines_index = 0;
|
||||
uint8_t is_in_multi_comment = 0;
|
||||
Arg* line_connection_arg = arg_newStr("");
|
||||
uint8_t is_line_connection = 0;
|
||||
char* out_ASM = NULL;
|
||||
char* single_ASM = NULL;
|
||||
uint32_t line_size = 0;
|
||||
char* sPyLines) {
|
||||
Stack tBlockStack;
|
||||
stack_init(&tBlockStack);
|
||||
Arg* aAsm = arg_newStr("");
|
||||
uint32_t uLinesOffset = 0;
|
||||
uint16_t uLinesNum = strCountSign(sPyLines, '\n') + 1;
|
||||
uint16_t uLinesIndex = 0;
|
||||
uint8_t bIsInMultiComment = 0;
|
||||
uint8_t bIsOneLineMultiComment = 0;
|
||||
Arg* aLineConnection = arg_newStr("");
|
||||
uint8_t bIsLineConnection = 0;
|
||||
char* sOutASM = NULL;
|
||||
char* sSingleASM = NULL;
|
||||
uint32_t uLineSize = 0;
|
||||
/* parse each line */
|
||||
while (1) {
|
||||
lines_index++;
|
||||
uLinesIndex++;
|
||||
Args buffs = {0};
|
||||
char* line_origin = NULL;
|
||||
char* line = NULL;
|
||||
char* sLineOrigin = NULL;
|
||||
char* sLine = NULL;
|
||||
|
||||
/* add void line to the end */
|
||||
if (lines_index >= lines_num + 1) {
|
||||
line = "";
|
||||
if (uLinesIndex >= uLinesNum + 1) {
|
||||
sLine = "";
|
||||
goto parse_line;
|
||||
}
|
||||
|
||||
/* get single line by pop multiline */
|
||||
line_origin = strsGetFirstToken(&buffs, py_lines + lines_offset, '\n');
|
||||
sLineOrigin = strsGetFirstToken(&buffs, sPyLines + uLinesOffset, '\n');
|
||||
|
||||
line = strsCopy(&buffs, line_origin);
|
||||
sLine = strsCopy(&buffs, sLineOrigin);
|
||||
/* line connection */
|
||||
if (is_line_connection) {
|
||||
is_line_connection = 0;
|
||||
line_connection_arg = arg_strAppend(line_connection_arg, line);
|
||||
line = strsCopy(&buffs, arg_getStr(line_connection_arg));
|
||||
if (bIsLineConnection) {
|
||||
bIsLineConnection = 0;
|
||||
aLineConnection = arg_strAppend(aLineConnection, sLine);
|
||||
sLine = strsCopy(&buffs, arg_getStr(aLineConnection));
|
||||
/* reflash the line_connection_arg */
|
||||
arg_deinit(line_connection_arg);
|
||||
line_connection_arg = arg_newStr("");
|
||||
arg_deinit(aLineConnection);
|
||||
aLineConnection = arg_newStr("");
|
||||
}
|
||||
|
||||
/* check connection */
|
||||
if ('\\' == line[strGetSize(line) - 1]) {
|
||||
if ('\\' == sLine[strGetSize(sLine) - 1]) {
|
||||
/* remove the '\\' */
|
||||
line[strGetSize(line) - 1] = '\0';
|
||||
is_line_connection = 1;
|
||||
line_connection_arg = arg_strAppend(line_connection_arg, line);
|
||||
sLine[strGetSize(sLine) - 1] = '\0';
|
||||
bIsLineConnection = 1;
|
||||
aLineConnection = arg_strAppend(aLineConnection, sLine);
|
||||
goto next_line;
|
||||
}
|
||||
Cursor_forEach(c, line) {
|
||||
Cursor_forEach(c, sLine) {
|
||||
Cursor_iterStart(&c);
|
||||
Cursor_iterEnd(&c);
|
||||
}
|
||||
Cursor_deinit(&c);
|
||||
/* auto connection */
|
||||
if (lines_index < lines_num) {
|
||||
if (uLinesIndex < uLinesNum) {
|
||||
if (c.branket_deepth > 0) {
|
||||
line_connection_arg = arg_strAppend(line_connection_arg, line);
|
||||
is_line_connection = 1;
|
||||
aLineConnection = arg_strAppend(aLineConnection, sLine);
|
||||
bIsLineConnection = 1;
|
||||
goto next_line;
|
||||
}
|
||||
}
|
||||
|
||||
/* branket match failed */
|
||||
if (c.branket_deepth != 0) {
|
||||
single_ASM = NULL;
|
||||
sSingleASM = NULL;
|
||||
goto parse_after;
|
||||
}
|
||||
|
||||
/* support Tab */
|
||||
line = strsReplace(&buffs, line, "\t", " ");
|
||||
sLine = strsReplace(&buffs, sLine, "\t", " ");
|
||||
/* remove \r */
|
||||
line = strsReplace(&buffs, line, "\r", "");
|
||||
sLine = strsReplace(&buffs, sLine, "\r", "");
|
||||
|
||||
/* filter for not end \n */
|
||||
if (Parser_isVoidLine(line)) {
|
||||
if (Parser_isVoidLine(sLine)) {
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
/* filter for multiline comment ''' or """ */
|
||||
if (Parser_checkIsMultiComment(line)) {
|
||||
is_in_multi_comment = ~is_in_multi_comment;
|
||||
if (Parser_checkIsMultiComment(sLine, &bIsOneLineMultiComment)) {
|
||||
bIsInMultiComment = ~bIsInMultiComment;
|
||||
/* skip one line multiline comment */
|
||||
if (bIsOneLineMultiComment) {
|
||||
bIsInMultiComment = 0;
|
||||
bIsOneLineMultiComment = 0;
|
||||
}
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
/* skipe multiline comment */
|
||||
if (is_in_multi_comment) {
|
||||
/* skip multiline comment */
|
||||
if (bIsInMultiComment) {
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
parse_line:
|
||||
/* parse single Line to Asm */
|
||||
single_ASM = Parser_LineToAsm(&buffs, line, &block_stack);
|
||||
sSingleASM = Parser_LineToAsm(&buffs, sLine, &tBlockStack);
|
||||
parse_after:
|
||||
if (NULL == single_ASM) {
|
||||
out_ASM = NULL;
|
||||
if (NULL == sSingleASM) {
|
||||
sOutASM = NULL;
|
||||
pika_platform_printf(
|
||||
"----------[%d]----------\r\n%s\r\n-------------------------"
|
||||
"\r\n",
|
||||
lines_index, line);
|
||||
uLinesIndex, sLine);
|
||||
strsDeinit(&buffs);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (NULL == bytecode_frame) {
|
||||
/* store ASM */
|
||||
asm_buff = arg_strAppend(asm_buff, single_ASM);
|
||||
aAsm = arg_strAppend(aAsm, sSingleASM);
|
||||
} else if (NULL == outBuffs) {
|
||||
/* store ByteCode */
|
||||
byteCodeFrame_appendFromAsm(bytecode_frame, single_ASM);
|
||||
byteCodeFrame_appendFromAsm(bytecode_frame, sSingleASM);
|
||||
}
|
||||
|
||||
next_line:
|
||||
if (lines_index < lines_num) {
|
||||
line_size = strGetSize(line_origin);
|
||||
lines_offset = lines_offset + line_size + 1;
|
||||
if (uLinesIndex < uLinesNum) {
|
||||
uLineSize = strGetSize(sLineOrigin);
|
||||
uLinesOffset = uLinesOffset + uLineSize + 1;
|
||||
}
|
||||
strsDeinit(&buffs);
|
||||
|
||||
/* exit when finished */
|
||||
if (lines_index >= lines_num + 1) {
|
||||
if (uLinesIndex >= uLinesNum + 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL != outBuffs) {
|
||||
/* load stored ASM */
|
||||
out_ASM = strsCopy(outBuffs, arg_getStr(asm_buff));
|
||||
sOutASM = strsCopy(outBuffs, arg_getStr(aAsm));
|
||||
} else {
|
||||
out_ASM = (char*)1;
|
||||
sOutASM = (char*)1;
|
||||
}
|
||||
goto exit;
|
||||
exit:
|
||||
if (NULL != asm_buff) {
|
||||
arg_deinit(asm_buff);
|
||||
if (NULL != aAsm) {
|
||||
arg_deinit(aAsm);
|
||||
}
|
||||
if (NULL != line_connection_arg) {
|
||||
arg_deinit(line_connection_arg);
|
||||
if (NULL != aLineConnection) {
|
||||
arg_deinit(aLineConnection);
|
||||
}
|
||||
stack_deinit(&block_stack);
|
||||
return out_ASM;
|
||||
stack_deinit(&tBlockStack);
|
||||
return sOutASM;
|
||||
};
|
||||
|
||||
PIKA_RES Parser_linesToBytes(ByteCodeFrame* bf, char* py_lines) {
|
||||
|
@ -5456,6 +5456,58 @@ TEST(parser, for_in_split) {
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(parser, common_issue_1b23f4c1bf) {
|
||||
g_PikaMemInfo.heapUsedMax = 0;
|
||||
Args* buffs = New_strBuff();
|
||||
char* pikaAsm =
|
||||
Parser_fileToAsm(buffs, "test/python/issue/common_issue_1b23f4c1bf.py");
|
||||
__platform_printf("%s", pikaAsm);
|
||||
|
||||
EXPECT_STREQ(pikaAsm,
|
||||
"B0\n"
|
||||
"0 CLS Test1()\n"
|
||||
"0 JMP 1\n"
|
||||
"B1\n"
|
||||
"0 RUN TinyObj\n"
|
||||
"0 OUT self\n"
|
||||
"B1\n"
|
||||
"0 RAS self\n"
|
||||
"B1\n"
|
||||
"0 RAS $origin\n"
|
||||
"B1\n"
|
||||
"0 NEW self\n"
|
||||
"0 RET \n"
|
||||
"B0\n"
|
||||
"0 CLS Test2()\n"
|
||||
"0 JMP 1\n"
|
||||
"B1\n"
|
||||
"0 RUN Test1\n"
|
||||
"0 OUT self\n"
|
||||
"B1\n"
|
||||
"0 RAS self\n"
|
||||
"B1\n"
|
||||
"0 DEF print(self)\n"
|
||||
"0 JMP 1\n"
|
||||
"B2\n"
|
||||
"1 STR Test2\n"
|
||||
"0 RUN print\n"
|
||||
"B2\n"
|
||||
"0 RET \n"
|
||||
"B1\n"
|
||||
"0 RAS $origin\n"
|
||||
"B1\n"
|
||||
"0 NEW self\n"
|
||||
"0 RET \n"
|
||||
"B0\n"
|
||||
"0 RUN Test2\n"
|
||||
"0 OUT a\n"
|
||||
"B0\n"
|
||||
"0 RUN a.print\n"
|
||||
"B0\n");
|
||||
args_deinit(buffs);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST_END
|
11
test/python/issue/common_issue_1b23f4c1bf.py
Normal file
11
test/python/issue/common_issue_1b23f4c1bf.py
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
class Test1:
|
||||
"""Test1 docstring"""
|
||||
|
||||
class Test2(Test1):
|
||||
"""Test2 docstring"""
|
||||
def print(self):
|
||||
print("Test2")
|
||||
|
||||
a = Test2()
|
||||
a.print()
|
Loading…
x
Reference in New Issue
Block a user