From 5ea48ef8060c9d1dce157ec8fed10624fbef8944 Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 15:16:48 +0800 Subject: [PATCH 1/9] feat: add linter action for antlr --- .github/workflows/antlr-lint.yml | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/antlr-lint.yml diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml new file mode 100644 index 0000000..9a68c52 --- /dev/null +++ b/.github/workflows/antlr-lint.yml @@ -0,0 +1,64 @@ +name: ANTLR Grammar Lint + +on: + push: + paths: + - '**/*.g4' + pull_request: + paths: + - '**/*.g4' + workflow_dispatch: + +jobs: + lint-grammars: + runs-on: ubuntu-latest + + strategy: + matrix: + include: + - dialect: redshift + path: redshift + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install antlr-v4-linter + run: | + pip install antlr4-python3-runtime + pip install antlr-v4-linter + + - name: Lint ${{ matrix.dialect }} grammar files + run: | + echo "Linting ANTLR grammar files for ${{ matrix.dialect }}" + + # Find all .g4 files in the dialect directory + find ${{ matrix.path }} -name "*.g4" -type f | while read -r file; do + echo "Checking: $file" + antlr-v4-linter "$file" || exit_code=$? + + if [ "${exit_code:-0}" -ne 0 ]; then + echo "::error file=$file::ANTLR grammar linting failed" + exit 1 + fi + done + + echo "✅ All grammar files for ${{ matrix.dialect }} passed linting" + + - name: Summary + if: always() + run: | + echo "## ANTLR Grammar Lint Results" >> $GITHUB_STEP_SUMMARY + echo "Dialect: **${{ matrix.dialect }}**" >> $GITHUB_STEP_SUMMARY + echo "Path: \`${{ matrix.path }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "### Files checked:" >> $GITHUB_STEP_SUMMARY + find ${{ matrix.path }} -name "*.g4" -type f | while read -r file; do + echo "- \`$file\`" >> $GITHUB_STEP_SUMMARY + done \ No newline at end of file From 2e496bd2c84deaf7df8a153f556bc985e0ae58a9 Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 15:18:48 +0800 Subject: [PATCH 2/9] chore: add speace to test --- redshift/RedshiftLexer.g4 | 1 + 1 file changed, 1 insertion(+) diff --git a/redshift/RedshiftLexer.g4 b/redshift/RedshiftLexer.g4 index d66e96b..5a9267a 100755 --- a/redshift/RedshiftLexer.g4 +++ b/redshift/RedshiftLexer.g4 @@ -3926,3 +3926,4 @@ EndDollarStringConstant {p.isTag()}? {l.popTag();} -> popMode ; + From 5960ff0c786d79b79cda7f02e9c1c4a4079db007 Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 15:24:05 +0800 Subject: [PATCH 3/9] chore: update --- .github/workflows/antlr-lint.yml | 42 +++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml index 9a68c52..40b8d96 100644 --- a/.github/workflows/antlr-lint.yml +++ b/.github/workflows/antlr-lint.yml @@ -20,38 +20,62 @@ jobs: path: redshift steps: - - name: Checkout code + - name: Checkout parser repository uses: actions/checkout@v4 + with: + path: parser + + - name: Checkout antlr-v4-linter repository + uses: actions/checkout@v4 + with: + repository: bytebase/antlr-v4-linter + path: antlr-v4-linter - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.x' + python-version: '3.10' - name: Install antlr-v4-linter run: | - pip install antlr4-python3-runtime - pip install antlr-v4-linter + cd antlr-v4-linter + pip install -e . + # Verify installation + which antlr-lint + antlr-lint --version || true - name: Lint ${{ matrix.dialect }} grammar files + working-directory: parser run: | echo "Linting ANTLR grammar files for ${{ matrix.dialect }}" + # Track if any errors occurred + has_errors=false + # Find all .g4 files in the dialect directory - find ${{ matrix.path }} -name "*.g4" -type f | while read -r file; do + for file in $(find ${{ matrix.path }} -name "*.g4" -type f); do echo "Checking: $file" - antlr-v4-linter "$file" || exit_code=$? - if [ "${exit_code:-0}" -ne 0 ]; then + # Run antlr-lint on the grammar file + if antlr-lint "$file"; then + echo "✅ $file: Passed linting" + else + echo "❌ $file: Failed linting" echo "::error file=$file::ANTLR grammar linting failed" - exit 1 + has_errors=true fi done - echo "✅ All grammar files for ${{ matrix.dialect }} passed linting" + if [ "$has_errors" = true ]; then + echo "❌ Grammar linting failed for ${{ matrix.dialect }}" + exit 1 + else + echo "✅ All grammar files for ${{ matrix.dialect }} passed linting" + fi - name: Summary if: always() + working-directory: parser run: | echo "## ANTLR Grammar Lint Results" >> $GITHUB_STEP_SUMMARY echo "Dialect: **${{ matrix.dialect }}**" >> $GITHUB_STEP_SUMMARY From a64375021a8d9693b2cf2311a18c0d84e53ce80f Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 15:25:29 +0800 Subject: [PATCH 4/9] chore: update --- .github/workflows/antlr-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml index 40b8d96..bc021a8 100644 --- a/.github/workflows/antlr-lint.yml +++ b/.github/workflows/antlr-lint.yml @@ -57,7 +57,7 @@ jobs: echo "Checking: $file" # Run antlr-lint on the grammar file - if antlr-lint "$file"; then + if antlr-lint lint "$file"; then echo "✅ $file: Passed linting" else echo "❌ $file: Failed linting" From 658707156adbea3445657393a8f83407516a49af Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 15:30:35 +0800 Subject: [PATCH 5/9] chore: update --- .github/workflows/antlr-lint.yml | 246 +++++++++++++++++++++++++++---- 1 file changed, 217 insertions(+), 29 deletions(-) diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml index bc021a8..d139762 100644 --- a/.github/workflows/antlr-lint.yml +++ b/.github/workflows/antlr-lint.yml @@ -1,88 +1,276 @@ name: ANTLR Grammar Lint +# This workflow runs the antlr-v4-linter on all ANTLR grammar files (.g4) +# to ensure they follow best practices and coding standards. +# +# The linter will check for: +# - Naming conventions (rules, tokens, labels) +# - Grammar complexity issues +# - Documentation requirements +# - Performance optimizations +# - Syntax and structural problems +# - Token management best practices + on: + # Trigger on push events that modify grammar files push: paths: - '**/*.g4' + - '.github/workflows/antlr-lint.yml' # Re-run if workflow itself changes + + # Trigger on pull requests that modify grammar files pull_request: paths: - '**/*.g4' + - '.github/workflows/antlr-lint.yml' + + # Allow manual triggering from Actions tab workflow_dispatch: + inputs: + verbose: + description: 'Enable verbose output' + required: false + default: 'false' + type: choice + options: + - 'true' + - 'false' jobs: lint-grammars: + name: Lint ANTLR Grammars runs-on: ubuntu-latest + # Define the dialects to check + # Add new dialects here as they are added to the repository strategy: matrix: include: - dialect: redshift path: redshift + # Future dialects can be added like: + # - dialect: postgres + # path: postgres + # - dialect: mysql + # path: mysql steps: - - name: Checkout parser repository + # Step 1: Checkout the parser repository containing grammar files + - name: 📥 Checkout parser repository uses: actions/checkout@v4 with: path: parser - - name: Checkout antlr-v4-linter repository + # Step 2: Checkout the antlr-v4-linter tool repository + - name: 📥 Checkout antlr-v4-linter tool uses: actions/checkout@v4 with: repository: bytebase/antlr-v4-linter path: antlr-v4-linter - - name: Set up Python + # Step 3: Set up Python environment + - name: 🐍 Set up Python uses: actions/setup-python@v5 with: python-version: '3.10' + cache: 'pip' + cache-dependency-path: 'antlr-v4-linter/pyproject.toml' - - name: Install antlr-v4-linter + # Step 4: Install the antlr-v4-linter tool + - name: 📦 Install antlr-v4-linter run: | + echo "Installing antlr-v4-linter and its dependencies..." cd antlr-v4-linter + + # Install in editable mode for development pip install -e . - # Verify installation + + # Verify installation was successful + echo "Verifying installation..." which antlr-lint - antlr-lint --version || true + antlr-lint --version || echo "Version command not available" + + # Show available commands + echo "Available commands:" + antlr-lint --help + + # Step 5: Create or check for configuration file + - name: ⚙️ Setup linter configuration + working-directory: parser + run: | + # Check if a custom configuration exists for this dialect + if [ -f "${{ matrix.path }}/antlr-lint.json" ]; then + echo "✅ Found custom configuration for ${{ matrix.dialect }}" + echo "CONFIG_FILE=${{ matrix.path }}/antlr-lint.json" >> $GITHUB_ENV + elif [ -f "antlr-lint.json" ]; then + echo "✅ Found global configuration" + echo "CONFIG_FILE=antlr-lint.json" >> $GITHUB_ENV + else + echo "ℹ️ No configuration found, using defaults" + echo "CONFIG_FILE=" >> $GITHUB_ENV + fi - - name: Lint ${{ matrix.dialect }} grammar files + # Step 6: Run the linter on grammar files with detailed output + - name: 🔍 Lint ${{ matrix.dialect }} grammar files working-directory: parser run: | - echo "Linting ANTLR grammar files for ${{ matrix.dialect }}" + echo "=========================================" + echo "Linting ANTLR grammar files for: ${{ matrix.dialect }}" + echo "Path: ${{ matrix.path }}" + echo "=========================================" + echo "" - # Track if any errors occurred - has_errors=false + # Initialize counters + total_files=0 + failed_files=0 + passed_files=0 - # Find all .g4 files in the dialect directory - for file in $(find ${{ matrix.path }} -name "*.g4" -type f); do - echo "Checking: $file" + # Create a temporary file to store all issues + issues_file=$(mktemp) + + # Process each .g4 file + for file in $(find ${{ matrix.path }} -name "*.g4" -type f | sort); do + total_files=$((total_files + 1)) + echo "📄 Checking: $file" + echo "----------------------------------------" + + # Prepare config option if config file exists + config_opt="" + if [ -n "$CONFIG_FILE" ]; then + config_opt="--config $CONFIG_FILE" + fi + + # Add verbose flag if requested + verbose_opt="" + if [ "${{ github.event.inputs.verbose }}" = "true" ]; then + verbose_opt="--verbose" + fi - # Run antlr-lint on the grammar file - if antlr-lint lint "$file"; then - echo "✅ $file: Passed linting" + # Run linter and capture output + output_file=$(mktemp) + if antlr-lint lint $verbose_opt $config_opt "$file" 2>&1 | tee "$output_file"; then + echo "✅ PASSED: No issues found" + passed_files=$((passed_files + 1)) else - echo "❌ $file: Failed linting" - echo "::error file=$file::ANTLR grammar linting failed" - has_errors=true + echo "❌ FAILED: Issues detected" + failed_files=$((failed_files + 1)) + + # Parse the output for GitHub annotations + # Extract file path, line numbers, and messages for GitHub annotations + while IFS= read -r line; do + # Look for patterns like "filename:line:column: severity: message" + # or "filename:line: severity: message" + if echo "$line" | grep -E "^.*\.g4:[0-9]+:" > /dev/null; then + # Extract components + file_path=$(echo "$line" | cut -d: -f1) + line_num=$(echo "$line" | cut -d: -f2) + + # Check if there's a column number + if echo "$line" | cut -d: -f3 | grep -E "^[0-9]+$" > /dev/null; then + col_num=$(echo "$line" | cut -d: -f3) + rest=$(echo "$line" | cut -d: -f4-) + else + col_num="" + rest=$(echo "$line" | cut -d: -f3-) + fi + + # Determine severity and message + if echo "$rest" | grep -i "error" > /dev/null; then + severity="error" + message=$(echo "$rest" | sed 's/^ *error: *//') + elif echo "$rest" | grep -i "warning" > /dev/null; then + severity="warning" + message=$(echo "$rest" | sed 's/^ *warning: *//') + else + severity="notice" + message=$(echo "$rest" | sed 's/^ *//') + fi + + # Output GitHub annotation + if [ -n "$col_num" ]; then + echo "::${severity} file=${file_path},line=${line_num},col=${col_num}::${message}" + else + echo "::${severity} file=${file_path},line=${line_num}::${message}" + fi + + # Store for summary + echo "${severity}: ${file_path}:${line_num} - ${message}" >> "$issues_file" + fi + done < "$output_file" + + # If no specific line annotations were found, create a general file-level annotation + if ! grep -q "::" "$output_file"; then + echo "::error file=${file}::ANTLR grammar linting failed. Check the workflow logs for details." + fi fi + + rm -f "$output_file" + echo "" done - if [ "$has_errors" = true ]; then + # Summary statistics + echo "=========================================" + echo "📊 Linting Summary for ${{ matrix.dialect }}" + echo "=========================================" + echo "Total files checked: ${total_files}" + echo "✅ Passed: ${passed_files}" + echo "❌ Failed: ${failed_files}" + echo "" + + # If there were failures, show a summary of issues + if [ $failed_files -gt 0 ]; then + echo "📋 Issues Summary:" + echo "----------------------------------------" + cat "$issues_file" | sort | uniq + echo "" echo "❌ Grammar linting failed for ${{ matrix.dialect }}" + echo "Please fix the issues above and try again." + rm -f "$issues_file" exit 1 else - echo "✅ All grammar files for ${{ matrix.dialect }} passed linting" + echo "✅ All grammar files for ${{ matrix.dialect }} passed linting!" + rm -f "$issues_file" fi - - name: Summary + # Step 7: Upload linter results as artifacts (useful for debugging) + - name: 📤 Upload linting results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: linting-results-${{ matrix.dialect }} + path: | + parser/${{ matrix.path }}/*.g4 + parser/antlr-lint.json + parser/${{ matrix.path }}/antlr-lint.json + retention-days: 7 + + # Step 8: Create job summary + - name: 📝 Create job summary if: always() working-directory: parser run: | - echo "## ANTLR Grammar Lint Results" >> $GITHUB_STEP_SUMMARY - echo "Dialect: **${{ matrix.dialect }}**" >> $GITHUB_STEP_SUMMARY - echo "Path: \`${{ matrix.path }}\`" >> $GITHUB_STEP_SUMMARY + echo "# 🔍 ANTLR Grammar Lint Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "## Dialect: \`${{ matrix.dialect }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Path:** \`${{ matrix.path }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + echo "### 📄 Grammar Files Checked:" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - echo "### Files checked:" >> $GITHUB_STEP_SUMMARY - find ${{ matrix.path }} -name "*.g4" -type f | while read -r file; do - echo "- \`$file\`" >> $GITHUB_STEP_SUMMARY - done \ No newline at end of file + echo "| File | Status |" >> $GITHUB_STEP_SUMMARY + echo "|------|--------|" >> $GITHUB_STEP_SUMMARY + + for file in $(find ${{ matrix.path }} -name "*.g4" -type f | sort); do + # Check if this file had issues (simplified check) + if antlr-lint lint "$file" > /dev/null 2>&1; then + echo "| \`${file}\` | ✅ Passed |" >> $GITHUB_STEP_SUMMARY + else + echo "| \`${file}\` | ❌ Failed |" >> $GITHUB_STEP_SUMMARY + fi + done + + echo "" >> $GITHUB_STEP_SUMMARY + echo "---" >> $GITHUB_STEP_SUMMARY + echo "*Workflow run at: $(date -u '+%Y-%m-%d %H:%M:%S UTC')*" >> $GITHUB_STEP_SUMMARY \ No newline at end of file From 7b463cddb5d15619a0806083a79a39924a6cc360 Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 15:36:01 +0800 Subject: [PATCH 6/9] chore: update --- .github/workflows/antlr-lint.yml | 66 ++++++++++++++++---------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml index d139762..69d362d 100644 --- a/.github/workflows/antlr-lint.yml +++ b/.github/workflows/antlr-lint.yml @@ -148,53 +148,47 @@ jobs: # Run linter and capture output output_file=$(mktemp) - if antlr-lint lint $verbose_opt $config_opt "$file" 2>&1 | tee "$output_file"; then - echo "✅ PASSED: No issues found" - passed_files=$((passed_files + 1)) - else + antlr-lint lint $verbose_opt $config_opt "$file" 2>&1 | tee "$output_file" + + # Check if there are any errors or warnings in the output + if grep -E "ERROR|WARNING" "$output_file" > /dev/null; then echo "❌ FAILED: Issues detected" failed_files=$((failed_files + 1)) # Parse the output for GitHub annotations - # Extract file path, line numbers, and messages for GitHub annotations + # Look for the table format with Location, Severity, Rule, and Message while IFS= read -r line; do - # Look for patterns like "filename:line:column: severity: message" - # or "filename:line: severity: message" - if echo "$line" | grep -E "^.*\.g4:[0-9]+:" > /dev/null; then - # Extract components - file_path=$(echo "$line" | cut -d: -f1) - line_num=$(echo "$line" | cut -d: -f2) + # Look for lines with the format: │ 827:1 │ ERROR │ S001 │ Message... + if echo "$line" | grep -E "^│ [0-9]+:[0-9]+" > /dev/null; then + # Extract location (line:column) + location=$(echo "$line" | sed -n 's/^│ *\([0-9]*:[0-9]*\).*/\1/p' | tr -d ' ') + line_num=$(echo "$location" | cut -d: -f1) + col_num=$(echo "$location" | cut -d: -f2) - # Check if there's a column number - if echo "$line" | cut -d: -f3 | grep -E "^[0-9]+$" > /dev/null; then - col_num=$(echo "$line" | cut -d: -f3) - rest=$(echo "$line" | cut -d: -f4-) - else - col_num="" - rest=$(echo "$line" | cut -d: -f3-) - fi - - # Determine severity and message - if echo "$rest" | grep -i "error" > /dev/null; then + # Extract severity + if echo "$line" | grep -i "ERROR" > /dev/null; then severity="error" - message=$(echo "$rest" | sed 's/^ *error: *//') - elif echo "$rest" | grep -i "warning" > /dev/null; then + elif echo "$line" | grep -i "WARNING" > /dev/null; then severity="warning" - message=$(echo "$rest" | sed 's/^ *warning: *//') else severity="notice" - message=$(echo "$rest" | sed 's/^ *//') fi + # Extract rule code + rule=$(echo "$line" | sed -n 's/.*│ *\([A-Z][0-9]*\) *│.*/\1/p') + + # Extract message - everything after the rule code + message=$(echo "$line" | sed -n 's/.*│ [A-Z][0-9]* *│ *\(.*\) *│$/\1/p' | sed 's/ *$//') + # Output GitHub annotation - if [ -n "$col_num" ]; then - echo "::${severity} file=${file_path},line=${line_num},col=${col_num}::${message}" + if [ -n "$col_num" ] && [ "$col_num" != "1" ]; then + echo "::${severity} file=${file},line=${line_num},col=${col_num}::[$rule] ${message}" else - echo "::${severity} file=${file_path},line=${line_num}::${message}" + echo "::${severity} file=${file},line=${line_num}::[$rule] ${message}" fi # Store for summary - echo "${severity}: ${file_path}:${line_num} - ${message}" >> "$issues_file" + echo "${severity}: ${file}:${line_num} - [$rule] ${message}" >> "$issues_file" fi done < "$output_file" @@ -202,6 +196,9 @@ jobs: if ! grep -q "::" "$output_file"; then echo "::error file=${file}::ANTLR grammar linting failed. Check the workflow logs for details." fi + else + echo "✅ PASSED: No issues found" + passed_files=$((passed_files + 1)) fi rm -f "$output_file" @@ -263,11 +260,12 @@ jobs: echo "|------|--------|" >> $GITHUB_STEP_SUMMARY for file in $(find ${{ matrix.path }} -name "*.g4" -type f | sort); do - # Check if this file had issues (simplified check) - if antlr-lint lint "$file" > /dev/null 2>&1; then - echo "| \`${file}\` | ✅ Passed |" >> $GITHUB_STEP_SUMMARY - else + # Check if this file had issues + output=$(antlr-lint lint "$file" 2>&1) + if echo "$output" | grep -E "ERROR|WARNING" > /dev/null; then echo "| \`${file}\` | ❌ Failed |" >> $GITHUB_STEP_SUMMARY + else + echo "| \`${file}\` | ✅ Passed |" >> $GITHUB_STEP_SUMMARY fi done From eb722e6076633a04047cbe450d70b34ba32544e4 Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 16:06:28 +0800 Subject: [PATCH 7/9] chore: update --- .github/workflows/antlr-lint.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml index 69d362d..e003367 100644 --- a/.github/workflows/antlr-lint.yml +++ b/.github/workflows/antlr-lint.yml @@ -12,8 +12,11 @@ name: ANTLR Grammar Lint # - Token management best practices on: - # Trigger on push events that modify grammar files + # Trigger on push events that modify grammar files (only on main/master branch) push: + branches: + - main + - master paths: - '**/*.g4' - '.github/workflows/antlr-lint.yml' # Re-run if workflow itself changes From 74e99e269cd216d13d5c1daf77ff438e68115201 Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 17:18:12 +0800 Subject: [PATCH 8/9] chore: update --- .github/workflows/antlr-lint.yml | 10 ++- antlr-lint.json | 102 +++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 antlr-lint.json diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml index e003367..cfbc350 100644 --- a/.github/workflows/antlr-lint.yml +++ b/.github/workflows/antlr-lint.yml @@ -262,9 +262,17 @@ jobs: echo "| File | Status |" >> $GITHUB_STEP_SUMMARY echo "|------|--------|" >> $GITHUB_STEP_SUMMARY + # Get config file path from environment + config_opt="" + if [ -f "${{ matrix.path }}/antlr-lint.json" ]; then + config_opt="--config ${{ matrix.path }}/antlr-lint.json" + elif [ -f "antlr-lint.json" ]; then + config_opt="--config antlr-lint.json" + fi + for file in $(find ${{ matrix.path }} -name "*.g4" -type f | sort); do # Check if this file had issues - output=$(antlr-lint lint "$file" 2>&1) + output=$(antlr-lint lint $config_opt "$file" 2>&1) if echo "$output" | grep -E "ERROR|WARNING" > /dev/null; then echo "| \`${file}\` | ❌ Failed |" >> $GITHUB_STEP_SUMMARY else diff --git a/antlr-lint.json b/antlr-lint.json new file mode 100644 index 0000000..1c9e961 --- /dev/null +++ b/antlr-lint.json @@ -0,0 +1,102 @@ +{ + "rules": { + "S001": { + "description": "Main parser rule should end with EOF token", + "enabled": true, + "severity": "error" + }, + "S002": { + "description": "Duplicate rule definition", + "enabled": true, + "severity": "warning" + }, + "S003": { + "description": "Invalid grammar declaration", + "enabled": true, + "severity": "error" + }, + "N001": { + "description": "Parser rule should start with lowercase letter", + "enabled": true, + "severity": "error" + }, + "N002": { + "description": "Lexer rule should start with uppercase letter", + "enabled": true, + "severity": "error" + }, + "N003": { + "description": "Rule name doesn't follow camelCase/UPPER_CASE convention", + "enabled": true, + "severity": "warning" + }, + "L001": { + "description": "Missing labels for alternatives in parser rules", + "enabled": true, + "severity": "warning" + }, + "L002": { + "description": "Inconsistent label naming convention", + "enabled": true, + "severity": "info" + }, + "L003": { + "description": "Duplicate label names within the same rule", + "enabled": true, + "severity": "warning" + }, + "C001": { + "description": "Rule exceeds complexity thresholds", + "enabled": true, + "severity": "warning", + "thresholds": { + "maxAlternatives": 10, + "maxNestingDepth": 5, + "maxTokens": 50 + } + }, + "C002": { + "description": "Deeply nested rule structure", + "enabled": true, + "severity": "warning" + }, + "C003": { + "description": "Very long rule definition (consider breaking it up)", + "enabled": true, + "severity": "info" + }, + "T001": { + "description": "Overlapping token definitions", + "enabled": true, + "severity": "warning" + }, + "T002": { + "description": "Unreachable token rule", + "enabled": true, + "severity": "warning" + }, + "T003": { + "description": "Token defined but never used", + "enabled": true, + "severity": "info" + }, + "E001": { + "description": "Missing error recovery strategy", + "enabled": false, + "severity": "info" + }, + "E002": { + "description": "Potential ambiguity in grammar", + "enabled": true, + "severity": "warning" + } + }, + "excludePatterns": [ + "*.generated.g4", + "*Test*.g4", + "node_modules/**/*.g4", + "dist/**/*.g4", + "build/**/*.g4" + ], + "outputFormat": "text" +} \ No newline at end of file From 2253224baf376cd640181ab2232cc8fe7b1dbdbb Mon Sep 17 00:00:00 2001 From: rebelice Date: Mon, 4 Aug 2025 17:20:24 +0800 Subject: [PATCH 9/9] chore: update --- .github/workflows/antlr-lint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/antlr-lint.yml b/.github/workflows/antlr-lint.yml index cfbc350..07d226b 100644 --- a/.github/workflows/antlr-lint.yml +++ b/.github/workflows/antlr-lint.yml @@ -271,8 +271,8 @@ jobs: fi for file in $(find ${{ matrix.path }} -name "*.g4" -type f | sort); do - # Check if this file had issues - output=$(antlr-lint lint $config_opt "$file" 2>&1) + # Check if this file had issues (ignore exit code) + output=$(antlr-lint lint $config_opt "$file" 2>&1 || true) if echo "$output" | grep -E "ERROR|WARNING" > /dev/null; then echo "| \`${file}\` | ❌ Failed |" >> $GITHUB_STEP_SUMMARY else