From 4fd2d52e9adaff5aa46a9101b0f21839936fe685 Mon Sep 17 00:00:00 2001 From: bfy <2568117980@qq.com> Date: Fri, 12 Jan 2024 04:49:09 +0800 Subject: [PATCH 01/16] add grammar lab --- CMakeLists.txt | 3 +- Dockerfile | 3 +- README.md | 3 +- grammar/C.g4 | 1116 ++++++++++++++++++++++++++++++++++++++++ grammar/CMakeLists.txt | 44 ++ grammar/README.md | 3 + grammar/main.cc | 21 + 7 files changed, 1190 insertions(+), 3 deletions(-) create mode 100644 grammar/C.g4 create mode 100644 grammar/CMakeLists.txt create mode 100644 grammar/README.md create mode 100644 grammar/main.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index a90b6a2..cb37fb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,11 @@ # cmake_minimum_required(VERSION 3.13.4) -project(SYsU-lang VERSION 12.0.0.20230529) +project(SYsU-lang VERSION 12.1.0.20240229) include(CPack) include(CTest) add_subdirectory(compiler) add_subdirectory(preprocessor) +add_subdirectory(grammar) add_subdirectory(lexer) add_subdirectory(parser) add_subdirectory(generator) diff --git a/Dockerfile b/Dockerfile index 9f863bc..4a15022 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,8 @@ RUN <') Identifier + | '++' + | '--' + )* + ; + +argumentExpressionList + : assignmentExpression (',' assignmentExpression)* + ; + +unaryExpression + : ('++' | '--' | 'sizeof')* ( + postfixExpression + | unaryOperator castExpression + | ('sizeof' | '_Alignof') '(' typeName ')' + | '&&' Identifier // GCC extension address of label + ) + ; + +unaryOperator + : '&' + | '*' + | '+' + | '-' + | '~' + | '!' + ; + +castExpression + : '__extension__'? '(' typeName ')' castExpression + | unaryExpression + | DigitSequence // for + ; + +multiplicativeExpression + : castExpression (('*' | '/' | '%') castExpression)* + ; + +additiveExpression + : multiplicativeExpression (('+' | '-') multiplicativeExpression)* + ; + +shiftExpression + : additiveExpression (('<<' | '>>') additiveExpression)* + ; + +relationalExpression + : shiftExpression (('<' | '>' | '<=' | '>=') shiftExpression)* + ; + +equalityExpression + : relationalExpression (('==' | '!=') relationalExpression)* + ; + +andExpression + : equalityExpression ('&' equalityExpression)* + ; + +exclusiveOrExpression + : andExpression ('^' andExpression)* + ; + +inclusiveOrExpression + : exclusiveOrExpression ('|' exclusiveOrExpression)* + ; + +logicalAndExpression + : inclusiveOrExpression ('&&' inclusiveOrExpression)* + ; + +logicalOrExpression + : logicalAndExpression ('||' logicalAndExpression)* + ; + +conditionalExpression + : logicalOrExpression ('?' expression ':' conditionalExpression)? + ; + +assignmentExpression + : conditionalExpression + | unaryExpression assignmentOperator assignmentExpression + | DigitSequence // for + ; + +assignmentOperator + : '=' + | '*=' + | '/=' + | '%=' + | '+=' + | '-=' + | '<<=' + | '>>=' + | '&=' + | '^=' + | '|=' + ; + +expression + : assignmentExpression (',' assignmentExpression)* + ; + +constantExpression + : conditionalExpression + ; + +declaration + : declarationSpecifiers initDeclaratorList? ';' + | staticAssertDeclaration + ; + +declarationSpecifiers + : declarationSpecifier+ + ; + +declarationSpecifiers2 + : declarationSpecifier+ + ; + +declarationSpecifier + : storageClassSpecifier + | typeSpecifier + | typeQualifier + | functionSpecifier + | alignmentSpecifier + ; + +initDeclaratorList + : initDeclarator (',' initDeclarator)* + ; + +initDeclarator + : declarator ('=' initializer)? + ; + +storageClassSpecifier + : 'typedef' + | 'extern' + | 'static' + | '_Thread_local' + | 'auto' + | 'register' + ; + +typeSpecifier + : 'void' + | 'char' + | 'short' + | 'int' + | 'long' + | 'float' + | 'double' + | 'signed' + | 'unsigned' + | '_Bool' + | '_Complex' + | '__m128' + | '__m128d' + | '__m128i' + | '__extension__' '(' ('__m128' | '__m128d' | '__m128i') ')' + | atomicTypeSpecifier + | structOrUnionSpecifier + | enumSpecifier + | typedefName + | '__typeof__' '(' constantExpression ')' // GCC extension + ; + +structOrUnionSpecifier + : structOrUnion Identifier? '{' structDeclarationList '}' + | structOrUnion Identifier + ; + +structOrUnion + : 'struct' + | 'union' + ; + +structDeclarationList + : structDeclaration+ + ; + +structDeclaration // The first two rules have priority order and cannot be simplified to one expression. + : specifierQualifierList structDeclaratorList ';' + | specifierQualifierList ';' + | staticAssertDeclaration + ; + +specifierQualifierList + : (typeSpecifier | typeQualifier) specifierQualifierList? + ; + +structDeclaratorList + : structDeclarator (',' structDeclarator)* + ; + +structDeclarator + : declarator + | declarator? ':' constantExpression + ; + +enumSpecifier + : 'enum' Identifier? '{' enumeratorList ','? '}' + | 'enum' Identifier + ; + +enumeratorList + : enumerator (',' enumerator)* + ; + +enumerator + : enumerationConstant ('=' constantExpression)? + ; + +enumerationConstant + : Identifier + ; + +atomicTypeSpecifier + : '_Atomic' '(' typeName ')' + ; + +typeQualifier + : 'const' + | 'restrict' + | 'volatile' + | '_Atomic' + ; + +functionSpecifier + : 'inline' + | '_Noreturn' + | '__inline__' // GCC extension + | '__stdcall' + | gccAttributeSpecifier + | '__declspec' '(' Identifier ')' + ; + +alignmentSpecifier + : '_Alignas' '(' (typeName | constantExpression) ')' + ; + +declarator + : pointer? directDeclarator gccDeclaratorExtension* + ; + +directDeclarator + : Identifier + | '(' declarator ')' + | directDeclarator '[' typeQualifierList? assignmentExpression? ']' + | directDeclarator '[' 'static' typeQualifierList? assignmentExpression ']' + | directDeclarator '[' typeQualifierList 'static' assignmentExpression ']' + | directDeclarator '[' typeQualifierList? '*' ']' + | directDeclarator '(' parameterTypeList ')' + | directDeclarator '(' identifierList? ')' + | Identifier ':' DigitSequence // bit field + | vcSpecificModifer Identifier // Visual C Extension + | '(' vcSpecificModifer declarator ')' // Visual C Extension + ; + +vcSpecificModifer + : '__cdecl' + | '__clrcall' + | '__stdcall' + | '__fastcall' + | '__thiscall' + | '__vectorcall' + ; + +gccDeclaratorExtension + : '__asm' '(' StringLiteral+ ')' + | gccAttributeSpecifier + ; + +gccAttributeSpecifier + : '__attribute__' '(' '(' gccAttributeList ')' ')' + ; + +gccAttributeList + : gccAttribute? (',' gccAttribute?)* + ; + +gccAttribute + : ~(',' | '(' | ')') // relaxed def for "identifier or reserved word" + ('(' argumentExpressionList? ')')? + ; + +nestedParenthesesBlock + : (~('(' | ')') | '(' nestedParenthesesBlock ')')* + ; + +pointer + : (('*' | '^') typeQualifierList?)+ // ^ - Blocks language extension + ; + +typeQualifierList + : typeQualifier+ + ; + +parameterTypeList + : parameterList (',' '...')? + ; + +parameterList + : parameterDeclaration (',' parameterDeclaration)* + ; + +parameterDeclaration + : declarationSpecifiers declarator + | declarationSpecifiers2 abstractDeclarator? + ; + +identifierList + : Identifier (',' Identifier)* + ; + +typeName + : specifierQualifierList abstractDeclarator? + ; + +abstractDeclarator + : pointer + | pointer? directAbstractDeclarator gccDeclaratorExtension* + ; + +directAbstractDeclarator + : '(' abstractDeclarator ')' gccDeclaratorExtension* + | '[' typeQualifierList? assignmentExpression? ']' + | '[' 'static' typeQualifierList? assignmentExpression ']' + | '[' typeQualifierList 'static' assignmentExpression ']' + | '[' '*' ']' + | '(' parameterTypeList? ')' gccDeclaratorExtension* + | directAbstractDeclarator '[' typeQualifierList? assignmentExpression? ']' + | directAbstractDeclarator '[' 'static' typeQualifierList? assignmentExpression ']' + | directAbstractDeclarator '[' typeQualifierList 'static' assignmentExpression ']' + | directAbstractDeclarator '[' '*' ']' + | directAbstractDeclarator '(' parameterTypeList? ')' gccDeclaratorExtension* + ; + +typedefName + : Identifier + ; + +initializer + : assignmentExpression + | '{' initializerList ','? '}' + ; + +initializerList + : designation? initializer (',' designation? initializer)* + ; + +designation + : designatorList '=' + ; + +designatorList + : designator+ + ; + +designator + : '[' constantExpression ']' + | '.' Identifier + ; + +staticAssertDeclaration + : '_Static_assert' '(' constantExpression ',' StringLiteral+ ')' ';' + ; + +statement + : labeledStatement + | compoundStatement + | expressionStatement + | selectionStatement + | iterationStatement + | jumpStatement + | ('__asm' | '__asm__') ('volatile' | '__volatile__') '(' ( + logicalOrExpression (',' logicalOrExpression)* + )? (':' (logicalOrExpression (',' logicalOrExpression)*)?)* ')' ';' + ; + +labeledStatement + : Identifier ':' statement? + | 'case' constantExpression ':' statement + | 'default' ':' statement + ; + +compoundStatement + : '{' blockItemList? '}' + ; + +blockItemList + : blockItem+ + ; + +blockItem + : statement + | declaration + ; + +expressionStatement + : expression? ';' + ; + +selectionStatement + : 'if' '(' expression ')' statement ('else' statement)? + | 'switch' '(' expression ')' statement + ; + +iterationStatement + : While '(' expression ')' statement + | Do statement While '(' expression ')' ';' + | For '(' forCondition ')' statement + ; + +// | 'for' '(' expression? ';' expression? ';' forUpdate? ')' statement +// | For '(' declaration expression? ';' expression? ')' statement + +forCondition + : (forDeclaration | expression?) ';' forExpression? ';' forExpression? + ; + +forDeclaration + : declarationSpecifiers initDeclaratorList? + ; + +forExpression + : assignmentExpression (',' assignmentExpression)* + ; + +jumpStatement + : ( + 'goto' Identifier + | 'continue' + | 'break' + | 'return' expression? + | 'goto' unaryExpression // GCC extension + ) ';' + ; + +compilationUnit + : translationUnit? EOF + ; + +translationUnit + : externalDeclaration+ + ; + +externalDeclaration + : functionDefinition + | declaration + | ';' // stray ; + ; + +functionDefinition + : declarationSpecifiers? declarator declarationList? compoundStatement + ; + +declarationList + : declaration+ + ; + +Auto + : 'auto' + ; + +Break + : 'break' + ; + +Case + : 'case' + ; + +Char + : 'char' + ; + +Const + : 'const' + ; + +Continue + : 'continue' + ; + +Default + : 'default' + ; + +Do + : 'do' + ; + +Double + : 'double' + ; + +Else + : 'else' + ; + +Enum + : 'enum' + ; + +Extern + : 'extern' + ; + +Float + : 'float' + ; + +For + : 'for' + ; + +Goto + : 'goto' + ; + +If + : 'if' + ; + +Inline + : 'inline' + ; + +Int + : 'int' + ; + +Long + : 'long' + ; + +Register + : 'register' + ; + +Restrict + : 'restrict' + ; + +Return + : 'return' + ; + +Short + : 'short' + ; + +Signed + : 'signed' + ; + +Sizeof + : 'sizeof' + ; + +Static + : 'static' + ; + +Struct + : 'struct' + ; + +Switch + : 'switch' + ; + +Typedef + : 'typedef' + ; + +Union + : 'union' + ; + +Unsigned + : 'unsigned' + ; + +Void + : 'void' + ; + +Volatile + : 'volatile' + ; + +While + : 'while' + ; + +Alignas + : '_Alignas' + ; + +Alignof + : '_Alignof' + ; + +Atomic + : '_Atomic' + ; + +Bool + : '_Bool' + ; + +Complex + : '_Complex' + ; + +Generic + : '_Generic' + ; + +Imaginary + : '_Imaginary' + ; + +Noreturn + : '_Noreturn' + ; + +StaticAssert + : '_Static_assert' + ; + +ThreadLocal + : '_Thread_local' + ; + +LeftParen + : '(' + ; + +RightParen + : ')' + ; + +LeftBracket + : '[' + ; + +RightBracket + : ']' + ; + +LeftBrace + : '{' + ; + +RightBrace + : '}' + ; + +Less + : '<' + ; + +LessEqual + : '<=' + ; + +Greater + : '>' + ; + +GreaterEqual + : '>=' + ; + +LeftShift + : '<<' + ; + +RightShift + : '>>' + ; + +Plus + : '+' + ; + +PlusPlus + : '++' + ; + +Minus + : '-' + ; + +MinusMinus + : '--' + ; + +Star + : '*' + ; + +Div + : '/' + ; + +Mod + : '%' + ; + +And + : '&' + ; + +Or + : '|' + ; + +AndAnd + : '&&' + ; + +OrOr + : '||' + ; + +Caret + : '^' + ; + +Not + : '!' + ; + +Tilde + : '~' + ; + +Question + : '?' + ; + +Colon + : ':' + ; + +Semi + : ';' + ; + +Comma + : ',' + ; + +Assign + : '=' + ; + +// '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' +StarAssign + : '*=' + ; + +DivAssign + : '/=' + ; + +ModAssign + : '%=' + ; + +PlusAssign + : '+=' + ; + +MinusAssign + : '-=' + ; + +LeftShiftAssign + : '<<=' + ; + +RightShiftAssign + : '>>=' + ; + +AndAssign + : '&=' + ; + +XorAssign + : '^=' + ; + +OrAssign + : '|=' + ; + +Equal + : '==' + ; + +NotEqual + : '!=' + ; + +Arrow + : '->' + ; + +Dot + : '.' + ; + +Ellipsis + : '...' + ; + +Identifier + : IdentifierNondigit (IdentifierNondigit | Digit)* + ; + +fragment IdentifierNondigit + : Nondigit + | UniversalCharacterName + //| // other implementation-defined characters... + ; + +fragment Nondigit + : [a-zA-Z_] + ; + +fragment Digit + : [0-9] + ; + +fragment UniversalCharacterName + : '\\u' HexQuad + | '\\U' HexQuad HexQuad + ; + +fragment HexQuad + : HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit + ; + +Constant + : IntegerConstant + | FloatingConstant + //| EnumerationConstant + | CharacterConstant + ; + +fragment IntegerConstant + : DecimalConstant IntegerSuffix? + | OctalConstant IntegerSuffix? + | HexadecimalConstant IntegerSuffix? + | BinaryConstant + ; + +fragment BinaryConstant + : '0' [bB] [0-1]+ + ; + +fragment DecimalConstant + : NonzeroDigit Digit* + ; + +fragment OctalConstant + : '0' OctalDigit* + ; + +fragment HexadecimalConstant + : HexadecimalPrefix HexadecimalDigit+ + ; + +fragment HexadecimalPrefix + : '0' [xX] + ; + +fragment NonzeroDigit + : [1-9] + ; + +fragment OctalDigit + : [0-7] + ; + +fragment HexadecimalDigit + : [0-9a-fA-F] + ; + +fragment IntegerSuffix + : UnsignedSuffix LongSuffix? + | UnsignedSuffix LongLongSuffix + | LongSuffix UnsignedSuffix? + | LongLongSuffix UnsignedSuffix? + ; + +fragment UnsignedSuffix + : [uU] + ; + +fragment LongSuffix + : [lL] + ; + +fragment LongLongSuffix + : 'll' + | 'LL' + ; + +fragment FloatingConstant + : DecimalFloatingConstant + | HexadecimalFloatingConstant + ; + +fragment DecimalFloatingConstant + : FractionalConstant ExponentPart? FloatingSuffix? + | DigitSequence ExponentPart FloatingSuffix? + ; + +fragment HexadecimalFloatingConstant + : HexadecimalPrefix (HexadecimalFractionalConstant | HexadecimalDigitSequence) BinaryExponentPart FloatingSuffix? + ; + +fragment FractionalConstant + : DigitSequence? '.' DigitSequence + | DigitSequence '.' + ; + +fragment ExponentPart + : [eE] Sign? DigitSequence + ; + +fragment Sign + : [+-] + ; + +DigitSequence + : Digit+ + ; + +fragment HexadecimalFractionalConstant + : HexadecimalDigitSequence? '.' HexadecimalDigitSequence + | HexadecimalDigitSequence '.' + ; + +fragment BinaryExponentPart + : [pP] Sign? DigitSequence + ; + +fragment HexadecimalDigitSequence + : HexadecimalDigit+ + ; + +fragment FloatingSuffix + : [flFL] + ; + +fragment CharacterConstant + : '\'' CCharSequence '\'' + | 'L\'' CCharSequence '\'' + | 'u\'' CCharSequence '\'' + | 'U\'' CCharSequence '\'' + ; + +fragment CCharSequence + : CChar+ + ; + +fragment CChar + : ~['\\\r\n] + | EscapeSequence + ; + +fragment EscapeSequence + : SimpleEscapeSequence + | OctalEscapeSequence + | HexadecimalEscapeSequence + | UniversalCharacterName + ; + +fragment SimpleEscapeSequence + : '\\' ['"?abfnrtv\\] + ; + +fragment OctalEscapeSequence + : '\\' OctalDigit OctalDigit? OctalDigit? + ; + +fragment HexadecimalEscapeSequence + : '\\x' HexadecimalDigit+ + ; + +StringLiteral + : EncodingPrefix? '"' SCharSequence? '"' + ; + +fragment EncodingPrefix + : 'u8' + | 'u' + | 'U' + | 'L' + ; + +fragment SCharSequence + : SChar+ + ; + +fragment SChar + : ~["\\\r\n] + | EscapeSequence + | '\\\n' // Added line + | '\\\r\n' // Added line + ; + +MultiLineMacro + : '#' (~[\n]*? '\\' '\r'? '\n')+ ~ [\n]+ -> channel (HIDDEN) + ; + +Directive + : '#' ~ [\n]* -> channel (HIDDEN) + ; + +// ignore the following asm blocks: +/* + asm + { + mfspr x, 286; + } + */ +AsmBlock + : 'asm' ~'{'* '{' ~'}'* '}' -> channel(HIDDEN) + ; + +Whitespace + : [ \t]+ -> channel(HIDDEN) + ; + +Newline + : ('\r' '\n'? | '\n') -> channel(HIDDEN) + ; + +BlockComment + : '/*' .*? '*/' -> channel(HIDDEN) + ; + +LineComment + : '//' ~[\r\n]* -> channel(HIDDEN) + ; \ No newline at end of file diff --git a/grammar/CMakeLists.txt b/grammar/CMakeLists.txt new file mode 100644 index 0000000..42c2d50 --- /dev/null +++ b/grammar/CMakeLists.txt @@ -0,0 +1,44 @@ +# Bring in the required packages +find_package(antlr4-runtime REQUIRED) + +if(NOT EXISTS "${ANTLR4_JAR_LOCATION}") + include(FetchContent) + file(DOWNLOAD + https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar + ${CMAKE_CURRENT_BINARY_DIR}/antlr-${ANTLR_VERSION}-complete.jar) + set(ANTLR4_JAR_LOCATION + ${CMAKE_CURRENT_BINARY_DIR}/antlr-${ANTLR_VERSION}-complete.jar) +endif() + +find_package(antlr4-generator REQUIRED) + +# generate lexer +antlr4_generate( + sysu_grammar + ${CMAKE_CURRENT_SOURCE_DIR}/C.g4 BOTH + TRUE TRUE "sysu_grammar") + +# add generated source files +add_executable(sysu-grammar main.cc ${ANTLR4_SRC_FILES_sysu_grammar}) +install(TARGETS sysu-grammar) + +# add directories for generated include files +target_include_directories( + sysu-grammar + PRIVATE ${ANTLR4_INCLUDE_DIR} ${ANTLR4_INCLUDE_DIR_sysu_grammar}) + +target_link_directories(sysu-grammar PRIVATE ${ANTLR4_LIB_DIR}) +target_link_libraries(sysu-grammar PRIVATE antlr4_shared) + +if(${ANTLR_VERSION} VERSION_LESS_EQUAL 4.10.1) + find_package(PkgConfig REQUIRED) + pkg_check_modules(UUID REQUIRED uuid) + target_link_directories(sysu-grammar PUBLIC ${UUID_LIBRARY_DIRS}) + target_link_libraries(sysu-grammar PUBLIC ${UUID_LIBRARIES}) +endif() + + +find_package(LLVM REQUIRED) +llvm_map_components_to_libnames(LLVM_LIBS support) +target_link_libraries(sysu-grammar PRIVATE ${LLVM_LIBS}) +target_include_directories(sysu-grammar PRIVATE ${LLVM_INCLUDE_DIRS}) diff --git a/grammar/README.md b/grammar/README.md new file mode 100644 index 0000000..5dbec69 --- /dev/null +++ b/grammar/README.md @@ -0,0 +1,3 @@ +# sysu-grammar + +TBD diff --git a/grammar/main.cc b/grammar/main.cc new file mode 100644 index 0000000..6eeebce --- /dev/null +++ b/grammar/main.cc @@ -0,0 +1,21 @@ +#include "CBaseListener.h" +#include "CBaseVisitor.h" +#include "CLexer.h" +#include "CListener.h" +#include "CParser.h" +#include "CVisitor.h" +#include +#include +#include +#include + +int main(int argc, char **argv) { + auto llvmin = llvm::MemoryBuffer::getFileOrSTDIN("-"); + auto inputbuffer = llvmin.get()->getBuffer(); + antlr4::ANTLRInputStream input(inputbuffer.begin(), inputbuffer.size()); + sysu_grammar::CLexer lexer(&input); + antlr4::CommonTokenStream tokens(&lexer); + tokens.fill(); + sysu_grammar::CParser parser(&tokens); + llvm::outs() << parser.compilationUnit()->toStringTree(&parser) << "\n"; +} \ No newline at end of file From 26cbe623ec9dbdc93ebbe1f7d8110e56bc030194 Mon Sep 17 00:00:00 2001 From: wu-kan Date: Fri, 12 Jan 2024 05:00:48 +0800 Subject: [PATCH 02/16] add pkg-config --- Dockerfile | 5 ++--- README.md | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4a15022..6a3f469 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,9 +36,8 @@ RUN < Date: Fri, 12 Jan 2024 05:04:44 +0800 Subject: [PATCH 03/16] fix dep --- Dockerfile | 2 +- README.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6a3f469..d0671e0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN <&1` 的输出。作为词法分析实验模块,本仓库中的 `sysu-lexer` 并不能处理完整的 SYsU,但提供了一个模板,需要学生将其词法规则补充完整([详细实验要求](lexer/README.md))。 From 7f06af26a6e5547d09ebe26fe3ada7aaeff20b96 Mon Sep 17 00:00:00 2001 From: wu-kan Date: Fri, 12 Jan 2024 10:53:28 +0800 Subject: [PATCH 04/16] try ubuntu:noble --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8aa6f64..9476e28 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -55,7 +55,7 @@ jobs: context: . tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - build-args: BASE_IMAGE=debian:bookworm + build-args: BASE_IMAGE=ubuntu:noble - name: Build Docker image for unstable-slim if: github.ref_name == 'unstable-slim' || github.base_ref == 'unstable-slim' @@ -91,7 +91,7 @@ jobs: context: . tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - build-args: BASE_IMAGE=debian:bookworm + build-args: BASE_IMAGE=ubuntu:noble platforms: linux/amd64,linux/arm64/v8 - name: Build and push Docker image for unstable-slim From 4163eb4cd1dde7b5643f1290e5e21316e7478eb3 Mon Sep 17 00:00:00 2001 From: wu-kan Date: Fri, 12 Jan 2024 11:13:15 +0800 Subject: [PATCH 05/16] use ubuntu:noble & llvm-17 --- .github/workflows/docker.yml | 31 ++++--------------------------- CMakeLists.txt | 6 +++--- Dockerfile | 2 +- README.md | 13 +++++-------- generator/README.md | 6 +++--- optimizer/README.md | 6 +++--- optimizer/main.cc | 2 +- parser/README.md | 10 +++++----- 8 files changed, 25 insertions(+), 51 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9476e28..70d1a1b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -7,10 +7,10 @@ name: docker on: push: - branches: [latest, unstable-slim] + branches: [latest] tags: ["*"] pull_request: - branches: [latest, unstable-slim] + branches: [latest] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -28,7 +28,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 with: - submodules: ${{ github.ref_name != 'unstable-slim' }} + submodules: True # Extract metadata (tags, labels) for Docker # https://github.com/docker/metadata-action @@ -48,7 +48,6 @@ jobs: # Build Docker image with Buildx # https://github.com/docker/build-push-action - name: Build Docker image - if: github.ref_name != 'unstable-slim' && github.base_ref != 'unstable-slim' uses: docker/build-push-action@v3 with: load: true @@ -57,16 +56,6 @@ jobs: labels: ${{ steps.meta.outputs.labels }} build-args: BASE_IMAGE=ubuntu:noble - - name: Build Docker image for unstable-slim - if: github.ref_name == 'unstable-slim' || github.base_ref == 'unstable-slim' - uses: docker/build-push-action@v3 - with: - load: true - context: . - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: BASE_IMAGE=debian:unstable-slim - - name: Run Tests continue-on-error: true run: docker run -e CTEST_OUTPUT_ON_FAILURE=1 --rm ${{ steps.meta.outputs.tags }} sh -c "cmake --build \$HOME/sysu/build -t test" @@ -84,7 +73,6 @@ jobs: # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action - name: Build and push Docker image - if: github.ref_name != 'unstable-slim' && github.base_ref != 'unstable-slim' uses: docker/build-push-action@v3 with: push: ${{ github.event_name != 'pull_request' }} @@ -92,15 +80,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: BASE_IMAGE=ubuntu:noble - platforms: linux/amd64,linux/arm64/v8 - - - name: Build and push Docker image for unstable-slim - if: github.ref_name == 'unstable-slim' || github.base_ref == 'unstable-slim' - uses: docker/build-push-action@v3 - with: - push: ${{ github.event_name != 'pull_request' }} - context: . - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: BASE_IMAGE=debian:unstable-slim - platforms: linux/amd64,linux/arm64/v8,linux/riscv64,linux/386,linux/arm/v7,linux/mips64le,linux/ppc64le,linux/s390x # ,linux/arm/v5 + platforms: linux/amd64,linux/arm64/v8,linux/arm/v7,linux/ppc64le,linux/s390x diff --git a/CMakeLists.txt b/CMakeLists.txt index cb37fb9..3af15d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ -# -cmake_minimum_required(VERSION 3.13.4) -project(SYsU-lang VERSION 12.1.0.20240229) +# +cmake_minimum_required(VERSION 3.20.0) +project(SYsU-lang VERSION 2404.0.0.20240229) include(CPack) include(CTest) add_subdirectory(compiler) diff --git a/Dockerfile b/Dockerfile index d0671e0..7457077 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.4 -ARG BASE_IMAGE=debian +ARG BASE_IMAGE=ubuntu FROM ${BASE_IMAGE} WORKDIR /autograder WORKDIR /workspace diff --git a/README.md b/README.md index a1d81c0..ea97cfa 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ SYsU 是一个教学语言,应用于中山大学(**S**un **Y**at-**s**en **U ## 编译运行 -需要注意的是,[SysY](https://gitlab.eduxiji.net/nscscc/compiler2021/-/blob/master/SysY%E8%AF%AD%E8%A8%80%E5%AE%9A%E4%B9%89.pdf) 语言允许编译时能够求值的 `const int` 作为数组大小,导致部分算例不能通过 `gcc` 的编译,因此为保持兼容推荐使用 `clang` 编译。经过测试的实验环境为 `debian:bookworm`。 +需要注意的是,[SysY](https://gitlab.eduxiji.net/nscscc/compiler2021/-/blob/master/SysY%E8%AF%AD%E8%A8%80%E5%AE%9A%E4%B9%89.pdf) 语言允许编译时能够求值的 `const int` 作为数组大小,导致部分算例不能通过 `gcc` 的编译,因此为保持兼容推荐使用 `clang` 编译。经过测试的实验环境为 `ubuntu:noble`。 ```bash # 安装依赖 @@ -353,16 +353,13 @@ git submodule update --init --recursive --depth 1 ### Q & A: 本项目的版本管理的规则是?为什么项目名为 SYsU-lang,而非 SYsU-compiler ? -目前本项目存在两个分支: +[`latest`](https://github.com/arcsysu/SYsU-lang/tree/latest) 分支下为中大课程教学中使用的代码,功能较为稳定,预期在 `ubuntu:noble` 环境中工作。文档可能不会及时更新,以对应 [Dockerfile](https://github.com/arcsysu/SYsU-lang/blob/latest/Dockerfile) 中的测试语句为准。 -- [`latest`](https://github.com/arcsysu/SYsU-lang/tree/latest) 分支下为中大课程教学中使用的代码,功能稳定,预期在 `debian:bookworm` 环境中工作。 -- [`unstable-slim`](https://github.com/arcsysu/SYsU-lang/tree/unstable-slim) 分支下为助教探索后续实验改革方案(如 mlir)的代码,预期在`debian:unstable-slim` 环境中工作。该分支中的文档可能不会及时更新,以对应 [Dockerfile](https://github.com/arcsysu/SYsU-lang/blob/unstable-slim/Dockerfile) 中的测试语句为准。 +对于中大以外的高校教学者与个人自学者,我们建议使用 [releases](https://github.com/arcsysu/SYsU-lang/releases) 中最新发布的实验框架源码以及对应版本号的 [docker image](https://hub.docker.com/r/wukan0621/sysu-lang)。它们可能在时间上略有落后,但经过了中大一学期的教学检验,不存在潜在的可能导致教学事故的错误。我们也十分欢迎来自你们的课堂反馈[![Discussions](https://img.shields.io/github/discussions/arcsysu/SYsU-lang)](https://github.com/arcsysu/SYsU-lang/discussions) 与改进建议[![Issues](https://img.shields.io/github/issues/arcsysu/SYsU-lang)](https://github.com/arcsysu/SYsU-lang/issues)[![Issues-pr](https://img.shields.io/github/issues-pr/arcsysu/SYsU-lang)](https://github.com/arcsysu/SYsU-lang/pulls) 。 -对于中大以外的高校教学者与个人自学者,我们建议使用 [releases](https://github.com/arcsysu/SYsU-lang/releases) 中最新发布的实验框架源码以及对应版本号的 [docker image](https://hub.docker.com/r/wukan0621/sysu-lang)。它们可能在时间上略有落后,但经过了中大一学期的教学检验,不存在潜在的可能导致教学事故的错误。我们也十分欢迎来自你们的课堂反馈[![Discussions](https://img.shields.io/github/discussions/arcsysu/SYsU-lang)](https://github.com/arcsysu/SYsU-lang/discussions) 与改进建议[![Issues](https://img.shields.io/github/issues/arcsysu/SYsU-lang)](https://github.com/arcsysu/SYsU-lang/issues)([![Issues-pr](https://img.shields.io/github/issues-pr/arcsysu/SYsU-lang)](https://github.com/arcsysu/SYsU-lang/pulls) 请提交至 `unstable-slim` 分支)。 +版本号的命名格式为 `...`,如 `2404.0.0.20240229`。一般来说,对于使用 `latest` 分支代码的用户,``、``、`` 发生变化时,我们建议尽快更新至最新版本。 -版本号的命名格式为 `...`,如 `11.0.7.20221118`。一般来说,对于使用 `latest` 分支代码的用户,``、``、`` 发生变化时,我们建议尽快更新至最新版本。 - -- `` 指示了该版本的软件依赖为对应的 debian 版本 +- `` 指示了该版本的软件依赖为对应的 ubuntu/debian 版本 - `` 指示了该版本的功能版本,不同 `` 间可能不直接兼容 - `` 指示了该版本的补丁版本,不同 `` 间预期可以直接更新,修正前一个版本中存在的问题 - `` 指示了当前版本代码(不含文档)的日期,可能存在微调,但不同 `` 的代码应当具有完全相同的表现 diff --git a/generator/README.md b/generator/README.md index 77e5d89..01b309c 100644 --- a/generator/README.md +++ b/generator/README.md @@ -135,8 +135,8 @@ $ echo $? # 在 Unix & Linux 中,可以通过 echo $? 来查看最后运行的 ## 你可能会感兴趣的 -- [Kaleidoscope: Code generation to LLVM IR](https://releases.llvm.org/14.0.0/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.html) +- [Kaleidoscope: Code generation to LLVM IR](https://releases.llvm.org/17.0.0/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.html) - [SYsU-lang 实验三快速上手](https://www.yuque.com/shuitang/rra4fg/bnqy1c) - [Viz.js — Graphviz in your browser.](http://viz-js.com/) -- [llvm::IRBuilder](https://github.com/llvm/llvm-project/blob/llvmorg-14.0.6/llvm/include/llvm/IR/IRBuilder.h) - - 该文件同样位于 debian:bookworm 中 [llvm-dev](https://packages.debian.org/bookworm/devel/llvm-dev) 包的 。 +- [llvm::IRBuilder](https://github.com/llvm/llvm-project/blob/llvmorg-17.0.6/llvm/include/llvm/IR/IRBuilder.h) + - 该文件同样位于 ubuntu:noble 中 [llvm-dev](https://packages.ubuntu.com/noble/llvm-dev) 包的 。 diff --git a/optimizer/README.md b/optimizer/README.md index 1bc70f7..ec5ba9c 100644 --- a/optimizer/README.md +++ b/optimizer/README.md @@ -46,7 +46,7 @@ 并思考,这些优化是否可以在语法树(即 `sysu-generator`)上完成?在这两个阶段各自的优点与缺点是什么? -如果你使用了来自 LLVM 的其他组件,你需要将其加入本目录下 `CMakeLists.txt` 中的 `llvm_map_components_to_libnames`,否则可能无法通过编译。你可以终端执行 `llvm-config --components`,查看所有的 LLVM 组件名称。然而,禁止使用任何 LLVM 自带的 [transform-passes](https://releases.llvm.org/14.0.0/docs/Passes.html#transform-passes)(当然,你被鼓励去学习这些 pass 的实现原理),助教会结合 `llvm-objdump` 等工具检查。 +如果你使用了来自 LLVM 的其他组件,你需要将其加入本目录下 `CMakeLists.txt` 中的 `llvm_map_components_to_libnames`,否则可能无法通过编译。你可以终端执行 `llvm-config --components`,查看所有的 LLVM 组件名称。然而,禁止使用任何 LLVM 自带的 [transform-passes](https://releases.llvm.org/17.0.0/docs/Passes.html#transform-passes)(当然,你被鼓励去学习这些 pass 的实现原理),助教会结合 `llvm-objdump` 等工具检查。 ### Q & A:有关 new pass manager 与 legacy pass manager @@ -93,8 +93,8 @@ Pass/PassManager 是 LLVM 里最重要的核心组件之一,自 LLVM 诞生以 ## 你可能会感兴趣的 -- [Writing an LLVM Pass](https://releases.llvm.org/14.0.0/docs/WritingAnLLVMNewPMPass.html) -- [Using the New Pass Manager](https://releases.llvm.org/14.0.0/docs/NewPassManager.html) +- [Writing an LLVM Pass](https://releases.llvm.org/17.0.0/docs/WritingAnLLVMNewPMPass.html) +- [Using the New Pass Manager](https://releases.llvm.org/17.0.0/docs/NewPassManager.html) - [Writing an LLVM Pass: 101 - LLVM 2019 tutorial](https://llvm.org/devmtg/2019-10/slides/Warzynski-WritingAnLLVMPass.pdf) - [Writing LLVM Pass in 2018-part I](https://medium.com/@mshockwave/writing-llvm-pass-in-2018-part-i-531c700e85eb) - [banach-space/llvm-tutor](https://github.com/banach-space/llvm-tutor) diff --git a/optimizer/main.cc b/optimizer/main.cc index ee3c6bf..1fcdffc 100644 --- a/optimizer/main.cc +++ b/optimizer/main.cc @@ -21,7 +21,7 @@ int main(int argc, char **argv) { "calls in the input IR file\n"); // Makes sure llvm_shutdown() is called (which cleans up LLVM objects) - // https://releases.llvm.org/14.0.0/docs/ProgrammersManual.html#ending-execution-with-llvm-shutdown + // https://releases.llvm.org/17.0.0/docs/ProgrammersManual.html#ending-execution-with-llvm-shutdown llvm::llvm_shutdown_obj SDO; // Parse the IR file passed on the command line. diff --git a/parser/README.md b/parser/README.md index 1883dc5..8f20333 100644 --- a/parser/README.md +++ b/parser/README.md @@ -255,7 +255,7 @@ flowchart TD; ### Q & A:为什么要输出到 `llvm::json`? 1. 输出到 json,便于使用 python 脚本和 clang 导出的语法树对比,自动批改。 -2. 输出到 json,因为 json 格式非常容易理解,不需要像 [LLVM 官方教程](https://releases.llvm.org/14.0.0/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html) 一样定义很多节点。 +2. 输出到 json,因为 json 格式非常容易理解,不需要像 [LLVM 官方教程](https://releases.llvm.org/17.0.0/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html) 一样定义很多节点。 3. 输出到 `llvm::json`,可以让同学们提前上手 LLVM 库的使用,平滑下一个实验的难度。 ## 评分规则 @@ -314,9 +314,9 @@ flowchart TD; - 输入一个经过预处理的 SYsU 源程序,输出其语法分析树。 - 建议:将 `sysu-lexer` 的核心代码打包成一个 `libsysuLexer.so`,将 `sysu-parser` 的核心代码打包成一个 `libsysuParser.so`,然后链接到到同一个 `main.cc`。 - 注意:`add_flex_bison_dependency` -7. 鉴于本次实验已经开始进入 LLVM 开发范畴,建议遵守 [LLVM Coding Standards](https://releases.llvm.org/14.0.0/docs/CodingStandards.html) +7. 鉴于本次实验已经开始进入 LLVM 开发范畴,建议遵守 [LLVM Coding Standards](https://releases.llvm.org/17.0.0/docs/CodingStandards.html) - 可以使用 `clang-tidy` 与 `clang-format` 工具检查你的代码是否规范,如 `cmake -DCMAKE_CXX_CLANG_TIDY=clang-tidy #...` - - 将 [LLVM Coding Standards](https://releases.llvm.org/14.0.0/docs/CodingStandards.html) 与 [GNU](https://www.gnu.org/prep/standards/standards.html)、[Google](https://google.github.io/styleguide/)、[Chromium](https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/c++/c++-dos-and-donts.md)、[Microsoft](https://docs.microsoft.com/zh-cn/dotnet/csharp/fundamentals/coding-style/coding-conventions)、[Mozilla](https://firefox-source-docs.mozilla.org/code-quality/coding-style/coding_style_cpp.html)、[WebKit](https://webkit.org/code-style-guidelines/) 等其他知名编程规范进行比较,选出一种或是基于他们归纳出一个你认为最合理的编程规范,编写对应的 `.clang-format` 与 `.clang-tidy` 文件,并在以后坚持使用下去!~~(就助教来说更加偏好 LLVM,毕竟没有人会比编译器更懂语言)~~ + - 将 [LLVM Coding Standards](https://releases.llvm.org/17.0.0/docs/CodingStandards.html) 与 [GNU](https://www.gnu.org/prep/standards/standards.html)、[Google](https://google.github.io/styleguide/)、[Chromium](https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/c++/c++-dos-and-donts.md)、[Microsoft](https://docs.microsoft.com/zh-cn/dotnet/csharp/fundamentals/coding-style/coding-conventions)、[Mozilla](https://firefox-source-docs.mozilla.org/code-quality/coding-style/coding_style_cpp.html)、[WebKit](https://webkit.org/code-style-guidelines/) 等其他知名编程规范进行比较,选出一种或是基于他们归纳出一个你认为最合理的编程规范,编写对应的 `.clang-format` 与 `.clang-tidy` 文件,并在以后坚持使用下去!~~(就助教来说更加偏好 LLVM,毕竟没有人会比编译器更懂语言)~~ 8. 改进这个实验模板(欢迎 PR!)。 9. Do what you want to do。 @@ -324,5 +324,5 @@ flowchart TD; - [GNU Bison - The Yacc-compatible Parser Generator](https://www.gnu.org/software/bison/manual/) - [FindBISON — CMake 3.13.5 Documentation](https://cmake.org/cmake/help/v3.13/module/FindBISON.html) -- [llvm::json](https://github.com/llvm/llvm-project/blob/llvmorg-14.0.6/llvm/include/llvm/Support/JSON.h) - - 该文件同样位于 debian:bookworm 中 [llvm-dev](https://packages.debian.org/bookworm/devel/llvm-dev) 包的 。 +- [llvm::json](https://github.com/llvm/llvm-project/blob/llvmorg-17.0.6/llvm/include/llvm/Support/JSON.h) + - 该文件同样位于 ubuntu:noble 中 [llvm-dev](https://packages.ubuntu.com/noble/llvm-dev) 包的 。 From ab07c35267c894ee73b6df7a573ad108019a4666 Mon Sep 17 00:00:00 2001 From: wu-kan Date: Fri, 12 Jan 2024 11:32:16 +0800 Subject: [PATCH 06/16] update dockerfile --- Dockerfile | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7457077..0148ccc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,36 +1,37 @@ # syntax=docker/dockerfile:1.4 ARG BASE_IMAGE=ubuntu +ARG WUK_SOURCE_DIR=/opt/SYsU-lang +ARG WUK_INSTALL_PREFIX=/opt/sysu FROM ${BASE_IMAGE} WORKDIR /autograder -WORKDIR /workspace -VOLUME /workspace -COPY </autograder/results/results.json + "${WUK_SOURCE_DIR}/**/*.sysu.c" >/autograder/results/results.json run.sh RUN < Date: Fri, 12 Jan 2024 11:35:08 +0800 Subject: [PATCH 07/16] fix dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0148ccc..10a3e6e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ ARG WUK_INSTALL_PREFIX=/opt/sysu FROM ${BASE_IMAGE} WORKDIR /autograder WORKDIR ${WUK_SOURCE_DIR} -ADD < Date: Fri, 12 Jan 2024 11:45:24 +0800 Subject: [PATCH 08/16] fix dockerfile --- Dockerfile | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index 10a3e6e..b594ff9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ # syntax=docker/dockerfile:1.4 ARG BASE_IMAGE=ubuntu -ARG WUK_SOURCE_DIR=/opt/SYsU-lang -ARG WUK_INSTALL_PREFIX=/opt/sysu +ENV SYSU_SOURCE_DIR=/opt/SYsU-lang +ENV SYSU_INSTALL_PREFIX=/opt/sysu FROM ${BASE_IMAGE} WORKDIR /autograder -WORKDIR ${WUK_SOURCE_DIR} -COPY </autograder/results/results.json + "${SYSU_SOURCE_DIR}/**/*.sysu.c" >/autograder/results/results.json run.sh RUN < Date: Fri, 12 Jan 2024 11:47:37 +0800 Subject: [PATCH 09/16] fix dockerfile --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index b594ff9..e80ab7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1.4 ARG BASE_IMAGE=ubuntu -ENV SYSU_SOURCE_DIR=/opt/SYsU-lang -ENV SYSU_INSTALL_PREFIX=/opt/sysu +ARG SYSU_SOURCE_DIR=/opt/SYsU-lang +ARG SYSU_INSTALL_PREFIX=/opt/sysu FROM ${BASE_IMAGE} WORKDIR /autograder WORKDIR ${SYSU_SOURCE_DIR} @@ -27,7 +27,7 @@ cp -r /opt/submission/*-Source/generator ${SYSU_SOURCE_DIR} rm -rf ${SYSU_SOURCE_DIR}/optimizer cp -r /opt/submission/*-Source/optimizer ${SYSU_SOURCE_DIR} rm -rf /opt/submission -\$HOME/build_install +\${SYSU_SOURCE_DIR}/build_install.sh mkdir -p /autograder/results sysu-compiler \\ --unittest=benchmark_generator_and_optimizer_1 \\ From 59be0ee90308c19664a09471e7a4f30eef93cf47 Mon Sep 17 00:00:00 2001 From: wu-kan Date: Fri, 12 Jan 2024 11:54:00 +0800 Subject: [PATCH 10/16] fix dockerfile --- Dockerfile | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index e80ab7f..87de020 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ # syntax=docker/dockerfile:1.4 ARG BASE_IMAGE=ubuntu -ARG SYSU_SOURCE_DIR=/opt/SYsU-lang -ARG SYSU_INSTALL_PREFIX=/opt/sysu FROM ${BASE_IMAGE} WORKDIR /autograder -WORKDIR ${SYSU_SOURCE_DIR} -COPY </autograder/results/results.json + "\$SYSU_SOURCE_DIR/**/*.sysu.c" >/autograder/results/results.json run.sh RUN < Date: Fri, 12 Jan 2024 12:00:40 +0800 Subject: [PATCH 11/16] fix dockerfile --- Dockerfile | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 87de020..aa214e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,18 +7,18 @@ ENV SYSU_INSTALL_PREFIX=/opt/sysu WORKDIR \$SYSU_SOURCE_DIR COPY < Date: Fri, 12 Jan 2024 12:04:58 +0800 Subject: [PATCH 12/16] fix dockerfile --- Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index aa214e4..e3de7ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,10 @@ ARG BASE_IMAGE=ubuntu FROM ${BASE_IMAGE} WORKDIR /autograder -ENV SYSU_SOURCE_DIR=/opt/SYsU-lang -ENV SYSU_INSTALL_PREFIX=/opt/sysu -WORKDIR \$SYSU_SOURCE_DIR -COPY < Date: Fri, 12 Jan 2024 12:22:17 +0800 Subject: [PATCH 13/16] fix dockerfile --- Dockerfile | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Dockerfile b/Dockerfile index e3de7ee..9e1f620 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,10 +2,8 @@ ARG BASE_IMAGE=ubuntu FROM ${BASE_IMAGE} WORKDIR /autograder -ARG SYSU_SOURCE_DIR=/opt/SYsU-lang -ARG SYSU_INSTALL_PREFIX=/opt/sysu -WORKDIR ${SYSU_SOURCE_DIR} -COPY </autograder/results/results.json + "/opt/SYsU-lang/**/*.sysu.c" >/autograder/results/results.json run.sh RUN < Date: Fri, 12 Jan 2024 12:23:43 +0800 Subject: [PATCH 14/16] CMAKE_CXX_STANDARD=17 --- Dockerfile | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 9e1f620..713a973 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,7 @@ cmake -G Ninja \\ -DCMAKE_BUILD_TYPE=RelWithDebInfo \\ -DCMAKE_C_COMPILER=clang \\ -DCMAKE_CXX_COMPILER=clang++ \\ + -DCMAKE_CXX_STANDARD=17 \\ -DCMAKE_INSTALL_PREFIX=\$2 \\ -DCMAKE_PREFIX_PATH="$(llvm-config --cmakedir)" \\ -DCPACK_SOURCE_IGNORE_FILES=".git/;tester/third_party/" \\ diff --git a/README.md b/README.md index ea97cfa..ffc57a6 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ cmake -G Ninja \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_CXX_STANDARD=17 \ -DCMAKE_INSTALL_PREFIX=$HOME/sysu \ -DCMAKE_PREFIX_PATH="$(llvm-config --cmakedir)" \ -DCPACK_SOURCE_IGNORE_FILES=".git/;tester/third_party/" \ From ca881343a65d11bf1f10ab6a031385df3fe2a659 Mon Sep 17 00:00:00 2001 From: wu-kan Date: Fri, 12 Jan 2024 12:25:19 +0800 Subject: [PATCH 15/16] fix dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 713a973..99839c7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ ARG BASE_IMAGE=ubuntu FROM ${BASE_IMAGE} WORKDIR /autograder -WORKDIR ${/opt/SYsU-lang} +WORKDIR /opt/SYsU-lang COPY < Date: Fri, 12 Jan 2024 13:49:01 +0800 Subject: [PATCH 16/16] grammar done!!! --- README.md | 45 ++++++++++++++++++++++---- compiler/sysu-compiler | 50 ++++++++++++++++++++--------- generator/README.md | 3 +- grammar/CMakeLists.txt | 1 - grammar/main.cc | 53 ++++++++++++++++++++++++++++++- optimizer/README.md | 3 +- tester/CMakeLists.txt | 72 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 199 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index ffc57a6..c863b83 100644 --- a/README.md +++ b/README.md @@ -167,11 +167,44 @@ int main(){ ### `grammar` -TBD +SYsU 的新语义分析器,产生类似于 `clang -cc1 -dump-tokens 2>&1`、`clang -cc1 -ast-dump=json` 的输出。作为语义分析实验模块,本仓库中的 `sysu-grammar` 并不能处理完整的 SYsU,但提供了一个模板,需要学生将其语义分析规则补充完整([详细实验要求](grammar/README.md))。 + +```bash +$ ( export PATH=$HOME/sysu/bin:$PATH \ + CPATH=$HOME/sysu/include:$CPATH \ + LIBRARY_PATH=$HOME/sysu/lib:$LIBRARY_PATH \ + LD_LIBRARY_PATH=$HOME/sysu/lib:$LD_LIBRARY_PATH && + sysu-preprocessor tester/functional/000_main.sysu.c | + sysu-grammar -dump-tokens ) +int 'int' Loc= +identifier 'main' Loc= +l_paren '(' Loc= +r_paren ')' Loc= +l_brace '{' Loc= +return 'return' Loc= +numeric_constant '3' Loc= +semi ';' Loc= +r_brace '}' Loc= +eof '' Loc= +``` + + + +```bash +$ ( export PATH=$HOME/sysu/bin:$PATH \ + CPATH=$HOME/sysu/include:$CPATH \ + LIBRARY_PATH=$HOME/sysu/lib:$LIBRARY_PATH \ + LD_LIBRARY_PATH=$HOME/sysu/lib:$LD_LIBRARY_PATH && + sysu-preprocessor tester/functional/000_main.sysu.c | + sysu-grammar ) +{"inner":[{"inner":[{"inner":[{"inner":[{"kind":"IntegerLiteral","value":"3"}],"kind":"ReturnStmt"}],"kind":"CompoundStmt"}],"kind":"FunctionDecl","name":"main"}],"kind":"TranslationUnitDecl"} +``` + + ### `lexer` -SYsU 的词法分析器,产生类似于 `clang -cc1 -dump-tokens 2>&1` 的输出。作为词法分析实验模块,本仓库中的 `sysu-lexer` 并不能处理完整的 SYsU,但提供了一个模板,需要学生将其词法规则补充完整([详细实验要求](lexer/README.md))。 +SYsU 的旧词法分析器,产生类似于 `clang -cc1 -dump-tokens 2>&1` 的输出。作为词法分析实验模块,本仓库中的 `sysu-lexer` 并不能处理完整的 SYsU,但提供了一个模板,需要学生将其词法规则补充完整([详细实验要求](lexer/README.md))。 ```bash $ ( export PATH=$HOME/sysu/bin:$PATH \ @@ -194,7 +227,7 @@ eof '' Loc= ### `parser` -SYsU 的语法分析器,接受来自 `sysu-lexer` 的输入,输出一个 json 格式的语法分析树(类似于 `clang -cc1 -ast-dump=json`)。作为语法分析实验模块,本仓库中的 `sysu-parser` 并不能处理完整的 SYsU,但提供了一个模板,需要学生将其语法规则补充完整([详细实验要求](parser/README.md))。 +SYsU 的旧文法分析器,接受来自 `sysu-lexer` 的输入,输出一个 json 格式的语法分析树(类似于 `clang -cc1 -ast-dump=json`)。作为语法分析实验模块,本仓库中的 `sysu-parser` 并不能处理完整的 SYsU,但提供了一个模板,需要学生将其语法规则补充完整([详细实验要求](parser/README.md))。 @@ -233,8 +266,7 @@ $ ( export PATH=$HOME/sysu/bin:$PATH \ LIBRARY_PATH=$HOME/sysu/lib:$LIBRARY_PATH \ LD_LIBRARY_PATH=$HOME/sysu/lib:$LD_LIBRARY_PATH && sysu-preprocessor tester/functional/000_main.sysu.c | - sysu-lexer | - sysu-parser | + sysu-grammar | sysu-generator ) ; ModuleID = '-' source_filename = "-" @@ -257,8 +289,7 @@ $ ( export PATH=$HOME/sysu/bin:$PATH \ LIBRARY_PATH=$HOME/sysu/lib:$LIBRARY_PATH \ LD_LIBRARY_PATH=$HOME/sysu/lib:$LD_LIBRARY_PATH && sysu-preprocessor tester/functional/000_main.sysu.c | - sysu-lexer | - sysu-parser | + sysu-grammar | sysu-generator | sysu-optimizer ) ================================================= diff --git a/compiler/sysu-compiler b/compiler/sysu-compiler index f13494a..2c76b50 100755 --- a/compiler/sysu-compiler +++ b/compiler/sysu-compiler @@ -32,7 +32,7 @@ import tempfile def main(*argv): - def unittest_parser(testcase, clang, preprocessor, parser, filenames, time_out): + def unittest_parser(testcase, clang, preprocessor, parser, filenames, time_out, grammar=None): def check_ast(ast0, ast1, testcase, command0, command1): def wk_exit(n): logging.getLogger(__name__).error("---") @@ -51,10 +51,10 @@ def main(*argv): key_inner = ["inner"] - if testcase in ["parser-0", "parser-1"]: + if testcase in ["parser-0", "parser-1", "grammar-4", "grammar-5"]: key_kind = ["kind", "name", "value"] skip_inner = ["InitListExpr"] # 跳过列表初始化 - elif testcase in ["parser-2"]: + elif testcase in ["parser-2", "grammar-6"]: key_kind = ["kind", "name", "value", "type"] skip_inner = [] else: @@ -112,7 +112,10 @@ def main(*argv): src = subprocess.run( command, timeout=time_out, stdout=subprocess.PIPE, shell=True).stdout command0 = command+" | "+clang + " -cc1 -ast-dump=json" - command1 = command+" | "+clang + " -cc1 -dump-tokens 2>&1 | "+parser + if grammar: + command1 = command+" | "+grammar + else: + command1 = command+" | "+clang + " -cc1 -dump-tokens 2>&1 | "+parser ast0 = None if filename.endswith(".sysu.c"): gz = filename[0:filename.rfind(".sysu.c")]+".json.gz" @@ -126,9 +129,14 @@ def main(*argv): stdout=subprocess.PIPE, shell=True).stdout ast0 = json.loads(ast0) gc.collect() - ast1 = json.loads(subprocess.run( - clang + " -cc1 -dump-tokens 2>&1 |"+parser, - input=src, timeout=time_out, stdout=subprocess.PIPE, shell=True).stdout) + if grammar: + ast1 = json.loads(subprocess.run( + grammar, + input=src, timeout=time_out, stdout=subprocess.PIPE, shell=True).stdout) + else: + ast1 = json.loads(subprocess.run( + clang + " -cc1 -dump-tokens 2>&1 |"+parser, + input=src, timeout=time_out, stdout=subprocess.PIPE, shell=True).stdout) gc.collect() r = check_ast(ast0, ast1, testcase, command0, command1) if r != 0: @@ -184,7 +192,7 @@ def main(*argv): tok0, str0, mid0, loc0 = split_tokens(tokens0[i]) tok1, str1, mid1, loc1 = split_tokens(tokens1[i]) - if testcase in ["lexer-3"]: + if testcase in ["lexer-3", "grammar-3"]: if mid0 != mid1: logging.getLogger(__name__).error( "\nfail: mid " + str(i+1) + "c" + str(i+1)) @@ -192,7 +200,7 @@ def main(*argv): logging.getLogger(__name__).error("---") logging.getLogger(__name__).error("> " + mid1) return wk_exit(-1) - if testcase in ["lexer-2", "lexer-3"]: + if testcase in ["lexer-2", "lexer-3", "grammar-2", "grammar-3"]: if loc0 != loc1: logging.getLogger(__name__).error( "\nfail: loc " + str(i+1) + "c" + str(i+1)) @@ -200,7 +208,7 @@ def main(*argv): logging.getLogger(__name__).error("---") logging.getLogger(__name__).error("> " + loc1) return wk_exit(-1) - if testcase in ["lexer-0", "lexer-1", "lexer-2", "lexer-3"]: + if testcase in ["lexer-0", "lexer-1", "lexer-2", "lexer-3", "grammar-0", "grammar-1", "grammar-2", "grammar-3"]: if tok0 != tok1: logging.getLogger(__name__).error( "\nfail: tok " + str(i+1) + "c" + str(i+1)) @@ -446,7 +454,7 @@ def main(*argv): parser = argparse.ArgumentParser( prog=os.path.basename(argv[0])) specs = ["clang", "sysu-preprocessor", "sysu-lexer", "sysu-parser", - "sysu-generator", "sysu-optimizer", "sysu-translator", "sysu-linker"] + "sysu-generator", "sysu-optimizer", "sysu-translator", "sysu-linker", "sysu-grammar"] for spec in specs: parser.add_argument( "--"+spec, @@ -503,14 +511,26 @@ def main(*argv): time_out = None if args.unittest_timeout >= 0: time_out = args.unittest_timeout - if "lexer" in args.unittest: - return unittest_lexer(args.unittest, args.clang, + for _test in ["lexer-0", "lexer-1", "lexer-2","lexer-3"]: + if _test in args.unittest: + return unittest_lexer(args.unittest, args.clang, args.sysu_preprocessor, args.sysu_lexer, filenames, time_out) - if "parser" in args.unittest: - return unittest_parser(args.unittest, args.clang, + for _test in ["parser-0", "parser-1", "parser-2","parser-3"]: + if _test in args.unittest: + return unittest_parser(args.unittest, args.clang, args.sysu_preprocessor, args.sysu_parser, filenames, time_out) + for _test in ["grammar-0", "grammar-1", "grammar-2","grammar-3"]: + if _test in args.unittest: + return unittest_lexer(args.unittest, args.clang, + args.sysu_preprocessor, args.sysu_grammar + " -dump-tokens ", + filenames, time_out) + for _test in ["grammar-4", "grammar-5", "grammar-6","grammar-7"]: + if _test in args.unittest: + return unittest_parser(args.unittest, args.clang, + args.sysu_preprocessor, None, + filenames, time_out, args.sysu_grammar) if "benchmark_generator_and_optimizer" in args.unittest: return benchmark_generator_and_optimizer( args.unittest, diff --git a/generator/README.md b/generator/README.md index 01b309c..2ac6713 100644 --- a/generator/README.md +++ b/generator/README.md @@ -60,8 +60,7 @@ $ ( export PATH=$HOME/sysu/bin:$PATH \ LIBRARY_PATH=$HOME/sysu/lib:$LIBRARY_PATH \ LD_LIBRARY_PATH=$HOME/sysu/lib:$LD_LIBRARY_PATH && sysu-preprocessor tester/functional/000_main.sysu.c | - sysu-lexer | - sysu-parser | + sysu-grammar | sysu-generator | lli --load=libsysy.so --load=libsysu.so ) # 该输出来自运行时库的计时统计 TOTAL: 0H-0M-0S-0us diff --git a/grammar/CMakeLists.txt b/grammar/CMakeLists.txt index 42c2d50..cac12c0 100644 --- a/grammar/CMakeLists.txt +++ b/grammar/CMakeLists.txt @@ -2,7 +2,6 @@ find_package(antlr4-runtime REQUIRED) if(NOT EXISTS "${ANTLR4_JAR_LOCATION}") - include(FetchContent) file(DOWNLOAD https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar ${CMAKE_CURRENT_BINARY_DIR}/antlr-${ANTLR_VERSION}-complete.jar) diff --git a/grammar/main.cc b/grammar/main.cc index 6eeebce..47b6152 100644 --- a/grammar/main.cc +++ b/grammar/main.cc @@ -1,3 +1,4 @@ +// 任 君 选 择 #include "CBaseListener.h" #include "CBaseVisitor.h" #include "CLexer.h" @@ -5,6 +6,7 @@ #include "CParser.h" #include "CVisitor.h" #include +#include #include #include #include @@ -16,6 +18,55 @@ int main(int argc, char **argv) { sysu_grammar::CLexer lexer(&input); antlr4::CommonTokenStream tokens(&lexer); tokens.fill(); + if (argc >= 2 && !std::strcmp(argv[1], "-dump-tokens")) { +// 请完成此处的词法分析器 +#if 0 + for (auto token : tokens.getTokens()) { + llvm::outs() << token->toString() << "\n"; + } +#else + llvm::outs() + << "int \'int\' " + "Loc= " + << "\n" + << "identifier \'main\' " + "Loc= " + << "\n" + << "l_paren \'(\' " + "Loc= " + << "\n" + << "r_paren \')\' " + "Loc= " + << "\n" + << "l_brace \'{\' " + "Loc= " + << "\n" + << "return \'return\' " + "Loc= " + << "\n" + << "numeric_constant \'3\' " + "Loc= " + << "\n" + << "semi \';\' " + "Loc= " + << "\n" + << "r_brace \'}\' " + "Loc= " + << "\n" + << "eof \'\' Loc= " + << "\n"; +#endif + return 0; + } sysu_grammar::CParser parser(&tokens); - llvm::outs() << parser.compilationUnit()->toStringTree(&parser) << "\n"; +// 请将此处的 ParseTree 转换为 AbstractSyntaxTree,简而言之就是把这颗树拍扁 +#if 0 + llvm::outs() << parser.compilationUnit()->toStringTree(&parser, true) << "\n"; +#else + llvm::outs() + << "{\"inner\":[{\"inner\":[{\"inner\":[{\"inner\":[{\"kind\":" + "\"IntegerLiteral\",\"value\":\"3\"}],\"kind\":\"ReturnStmt\"}]," + "\"kind\":\"CompoundStmt\"}],\"kind\":\"FunctionDecl\",\"name\":" + "\"main\"}],\"kind\":\"TranslationUnitDecl\"}"; +#endif } \ No newline at end of file diff --git a/optimizer/README.md b/optimizer/README.md index ec5ba9c..6549430 100644 --- a/optimizer/README.md +++ b/optimizer/README.md @@ -10,8 +10,7 @@ LIBRARY_PATH=$HOME/sysu/lib:$LIBRARY_PATH \ LD_LIBRARY_PATH=$HOME/sysu/lib:$LD_LIBRARY_PATH && sysu-preprocessor tester/functional/000_main.sysu.c | - sysu-lexer | - sysu-parser | + sysu-grammar | sysu-generator | sysu-optimizer ) # or diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index d1846a1..007c47a 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -87,6 +87,78 @@ foreach(_test parser-1 parser-2 parser-3) ) endforeach() +foreach(_test grammar-0) + add_test( + NAME ${_test} + COMMAND + ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/../compiler/sysu-compiler --unittest ${_test} + --sysu-preprocessor + ${CMAKE_CURRENT_SOURCE_DIR}/../preprocessor/sysu-preprocessor + --sysu-grammar $ + "${CMAKE_CURRENT_SOURCE_DIR}/functional/000_main.sysu.c") + set_tests_properties( + ${_test} + PROPERTIES + ENVIRONMENT + "CPATH=${CMAKE_CURRENT_SOURCE_DIR}/../librarian/include:$ENV{CPATH};LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LIBRARY_PATH};LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LD_LIBRARY_PATH}" + ) +endforeach() + +foreach(_test grammar-1 grammar-2 grammar-3) + add_test( + NAME ${_test} + COMMAND + ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/../compiler/sysu-compiler --unittest ${_test} + --sysu-preprocessor + ${CMAKE_CURRENT_SOURCE_DIR}/../preprocessor/sysu-preprocessor + --sysu-grammar $ + "${CMAKE_CURRENT_SOURCE_DIR}/**/*.sysu.c") + set_tests_properties( + ${_test} + PROPERTIES + ENVIRONMENT + "CPATH=${CMAKE_CURRENT_SOURCE_DIR}/../librarian/include:$ENV{CPATH};LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LIBRARY_PATH};LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LD_LIBRARY_PATH}" + ) +endforeach() + +foreach(_test grammar-4) + add_test( + NAME ${_test} + COMMAND + ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/../compiler/sysu-compiler --unittest ${_test} + --sysu-preprocessor + ${CMAKE_CURRENT_SOURCE_DIR}/../preprocessor/sysu-preprocessor + --sysu-grammar $ + "${CMAKE_CURRENT_SOURCE_DIR}/functional/000_main.sysu.c") + set_tests_properties( + ${_test} + PROPERTIES + ENVIRONMENT + "CPATH=${CMAKE_CURRENT_SOURCE_DIR}/../librarian/include:$ENV{CPATH};LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LIBRARY_PATH};LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LD_LIBRARY_PATH}" + ) +endforeach() + +foreach(_test grammar-5 grammar-6 grammar-7) + add_test( + NAME ${_test} + COMMAND + ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/../compiler/sysu-compiler --unittest ${_test} + --sysu-preprocessor + ${CMAKE_CURRENT_SOURCE_DIR}/../preprocessor/sysu-preprocessor + --sysu-grammar $ + "${CMAKE_CURRENT_SOURCE_DIR}/**/*.sysu.c") + set_tests_properties( + ${_test} + PROPERTIES + ENVIRONMENT + "CPATH=${CMAKE_CURRENT_SOURCE_DIR}/../librarian/include:$ENV{CPATH};LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LIBRARY_PATH};LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../librarian/lib:$ENV{LD_LIBRARY_PATH}" + ) +endforeach() + foreach(_test benchmark_generator_and_optimizer_0) add_test( NAME ${_test}