Skip to content

Commit b686024

Browse files
committed
feat(isc): strip comments in sub rules, add space/non_boundary primitives
Codemod: strip # comments from sub rule lines BEFORE tokenizing. Prevents comment text like '# comment with after keyword' from being parsed as a real constraint. Grammar: accept 'space' and 'non_boundary' as zero-width primitives. Verification: 160/289 maps equivalent (55%).
1 parent cc65e51 commit b686024

2 files changed

Lines changed: 29 additions & 10 deletions

File tree

exe/codemod-imp-to-isc

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,11 @@ module Interscript
497497
# Drop the trailing newline
498498
line = line.chomp
499499

500+
# Strip comments (# ... to end of line) but only when # is at start of
501+
# token (not inside a string). Walk char by char.
502+
line = strip_comments(line)
503+
500504
# Split into tokens: handle hash rockets, commas, parens, strings.
501-
# We do this by walking the string with a simple state machine.
502505
tokens = []
503506
current = +""
504507
in_string = nil
@@ -522,31 +525,45 @@ module Interscript
522525
elsif paren_depth.zero? && (c == "," || (c == "=" && line[_i + 1] == ">"))
523526
tokens << current.strip
524527
current = +""
525-
# Skip the comma or `=>`
526-
if c == "="
527-
@scanner.unscan if false # can't unscan, line already consumed
528-
end
529528
else
530529
current << c
531530
end
532531
end
533532
tokens << current.strip unless current.strip.empty?
534533

535-
# Drop hash rocket tokens (already handled above by treating `=>` like `,`)
536534
tokens = tokens.reject { |t| t == "=>" }
537535

538-
# First token = from, second = to, rest = constraints
539536
from_expr = normalize_expr(tokens.shift.to_s)
540537
to_expr = normalize_expr(tokens.shift.to_s)
541538
constraints_str = tokens.join(" ")
542539

543-
# Strip the `before:` etc colon (the codemod dropped these elsewhere,
544-
# but here we want to normalize: `before: X` -> `before X`)
545540
constraints_str = constraints_str.gsub(/(before|after|not_before|not_after)\s*:/, '\1')
546541

547542
[from_expr, to_expr, constraints_str]
548543
end
549544

545+
# Remove `# ...` comments from a line, respecting quoted strings.
546+
def strip_comments(line)
547+
result = +""
548+
in_string = nil
549+
line.each_char do |c|
550+
if in_string
551+
result << c
552+
if c == in_string && result[-2] != "\\"
553+
in_string = nil
554+
end
555+
elsif c == '"' || c == "'"
556+
in_string = c
557+
result << c
558+
elsif c == "#"
559+
break
560+
else
561+
result << c
562+
end
563+
end
564+
result
565+
end
566+
550567
# A "single atom" expression is one quoted string, `none`, `boundary`,
551568
# `line_start`, `line_end`, `word_boundary`, or a bare alias identifier.
552569
# Anything with `+`, `any(`, `capture(`, `maybe(`, or concatenation is

lib/interscript/isc/grammar/concerns/items.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ module Items
2626
str("boundary") |
2727
str("line_start") |
2828
str("line_end") |
29-
str("word_boundary")
29+
str("word_boundary") |
30+
str("space") |
31+
str("non_boundary")
3032
).as(:primitive)
3133
end
3234

0 commit comments

Comments
 (0)