`
RednaxelaFX
  • 浏览: 3039700 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

将ANTLR生成的.tokens文件重格式化(Ruby版)-20080626更新

    博客分类:
  • Ruby
阅读更多
相关链接:
将ANTLR生成的.tokens文件重格式化(C++版)
将ANTLR生成的.tokens文件重格式化(C#版)

ANTLR在对.g的语法文件生成Java代码的同时,还会生成一个.tokens文件来方便别的parser(例如说接在source parser后的tree parser)使用同样的token定义。
不过这tokens文件看起来不总是那么方便。举例来说,昨天发的帖里Dolphin.g,对应的Dolphin.tokens文件如下:
Dolphin.tokens:
FUNCTION=4
NullLiteral=31
WHILE=18
FloatTypeSuffix=38
OctalLiteral=33
CharacterLiteral=28
LBRACE=11
LineComment=44
FOR=19
DO=17
Exponent=37
RelationalOperator=24
HexDigit=35
BREAK=20
Identifier=5
LPAREN=6
IF=16
AssignmentOperator=15
RPAREN=7
CONTINUE=21
Comment=43
COMMA=8
AddOperator=25
RETURN=22
TypeSpecifier=10
VAR=13
HexLiteral=32
RBRACE=12
IntegerTypeSuffix=36
SEMICOLON=14
DecimalLiteral=34
AssignmentShorthandOperator=23
COLON=9
StringLiteral=29
WS=42
UnicodeEscape=40
FloatingPointLiteral=27
MulOperator=26
EscapeSequence=39
OctalEscape=41
BooleanLiteral=30


当我知道期望的token类型的名字时,上面的tokens文件可以帮我找到对应的数值常量;但当我在Eclipse里调试时,看到的只有"type",也就是token类型对应的数值常量,要找对应的名字就比较麻烦了。上上下下看得眼花。

于是我自然希望顺序能颠倒一下,数值常量在前,名字在后,并且按照数值常量的大小按升序排序。像这样:
Dolphin.tokens.txt:
4=FUNCTION
5=Identifier
6=LPAREN
7=RPAREN
8=COMMA
9=COLON
10=TypeSpecifier
11=LBRACE
12=RBRACE
13=VAR
14=SEMICOLON
15=AssignmentOperator
16=IF
17=DO
18=WHILE
19=FOR
20=BREAK
21=CONTINUE
22=RETURN
23=AssignmentShorthandOperator
24=RelationalOperator
25=AddOperator
26=MulOperator
27=FloatingPointLiteral
28=CharacterLiteral
29=StringLiteral
30=BooleanLiteral
31=NullLiteral
32=HexLiteral
33=OctalLiteral
34=DecimalLiteral
35=HexDigit
36=IntegerTypeSuffix
37=Exponent
38=FloatTypeSuffix
39=EscapeSequence
40=UnicodeEscape
41=OctalEscape
42=WS
43=Comment
44=LineComment


这种苦力事情显然不值得开动笨重的Java或者C#,哦别提C++和C了。这个时候最能让我偷懒的办法就是最好的办法 XD

于是写了这样的一段Ruby脚本:
reformat.rb:
#!/usr/bin/env ruby
# reformat.rb

## Reformat a token file produced by ANTLR to the format:
## token_number=token_name

def reformat( infile, outfile )
  lines = []
  
  File.open infile, "r" do |file|
    file.each do |line|
      lines << "#{$2}=#{$1}" if line.chomp =~ /^([^=]+)=([0-9]+)$/
    end
  end
  
  # yeah, i know this is slow, but we're not
  # pushing for speed anyway
  lines = lines.sort_by do |line|
    line =~ /^[0-9]+/
    $&.to_i
  end
  
  File.open outfile, "w" do |file|
    lines.each { |line| file.puts line }
  end
end

if ARGV.size != 2
  puts "Usage: #{$0} [token file] [output file]"
  exit
end

infile, outfile = ARGV
reformat infile, outfile


好吧,这段代码一点也不美。要是能把读写文件放在同一个循环里,顺带能排序就好了。这段代码仅有的好处就是没花多少时间去写而且功能符合我的需要,以后还可以继续用。
Ruby才刚开始用,希望有高手能指点指点怎么改进一下这代码~~

(20080328更新:加入了下面的版本的代码。避免在传给sort_by的block中使用正则表达式。虽然在循环里用了to_i还是稍嫌不爽)
(20080329更新:发觉应该用Enumerable#grep的。也不用在sort_by的block里用to_i了。很好,更简洁了)
(20080626更新:File.open还是用带block的方式好。IO对象不关掉始终是不放心。另外,原本定义了一个类当作tuple用,想想其实没必要定义个类,直接用数组就够了)

reformat.rb:
#!/usr/bin/env ruby
# reformat.rb

## Reformat a token file produced by ANTLR to the format:
## token_number=token_name

def reformat( infile, outfile )
  lines = []
  File.open infile, "r" do |file|
    file.grep /^([^=]+)=([0-9]+)$/ do |line|
      lines.push [ $1, $2.to_i ] # name, value = $1, $2
    end
  end
  lines = lines.sort_by { |pair| pair[1] }
  File.open outfile, "w" do |file|
    lines.each { |pair| file.puts "#{pair[1]}=#{pair[0]}" }
  end
end

if ARGV.size != 2
  puts "Usage: #{$0} [token file] [output file]"
  exit
end

infile, outfile = ARGV
reformat infile, outfile


(20100812更新:
当初写的Ruby跟现在写的Ruby果然还是比较不一样……)

#!/usr/bin/env ruby

def reformat(infile, outfile)
  lines = File.readlines(infile).map {|l| l.chomp.split '='}.sort_by {|l| l.last.to_i}
  File.open(outfile, 'w') {|f| f.puts lines.map {|l| l.reverse.join('=')}}
end

$*.size != 2 || reformat(*$*) and puts "Usage: #{$0} [token file] [output file]"

本来还是写ARGV比较好,不过能凑出(*$*)这么可爱的表情实在是忍不住想把ARGV写成$*啊 =_=|||

====================================================================

P.S. 当然这东西不用Ruby还有更快的实现方法,直接用UltraEdit就行。
首先确保UltraEdit的Advanced->Configuration->Search->Regular Expression Engine里,"Perl compatible Regular Expressions"打上了钩。(我不熟悉UE自己定义的Regex的规格,试了好几次都不行,放弃了,换回相对熟悉些的Perl系Regex)
然后Ctrl+R(或者Search->Replace),在Find What里输入
^([^=]+)=([0-9]+)$

在Replace With里输入
\2=\1

接着File->Sort->Advanced Sort/Options...,选Numeric Sort,完事。
3
0
分享到:
评论

相关推荐

    antlr-3.3.tar.gz_antlr_antlr-2.7.5.tar.gz

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种语言和系统的开发,包括编程语言、配置文件、通信协议等。这...

    开源项目-antlr-antlr4.zip

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR4是它的最新版本,它提供了显著的性能提升和许多新特性。这个开源项目“antlr-...

    antlr_2.7.6.jar.zip

    ANTLR( Anatomy of a Little Language Translator)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR主要用于构建语言、工具和框架。从简单的命令行工具到复杂的编程语言,...

    antlr-runtime-3.1.3.jar.zip

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于构建语言、工具和框架,如SQL查询解析器、XML处理器、配置文件...

    antlr-v4jar包和使用教程

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种语言和系统的开发,包括数据库查询解析、配置文件处理、编程...

    antlr.jar和json.jar

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR被广泛应用于各种编程语言的编译器和解释器的开发,它能生成Java、C#、Python...

    antlr2peg:从ANTLR .g4文件到PEG语法的幼稚翻译器

    这些文件包含了词法符号(tokens)和语法规则,允许ANTLR生成对应目标语言的解析器和词法分析器。 PEG(Parsers Expression Grammar)是一种上下文无关的语法表示法,全称为解析表达式语法。与传统的LL或LR解析器...

    antlr-intellij-plugin-v4-1.18-2020.zip

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架。ANTLR生成Java、C#、Python、JavaScript等语言...

    Antlr简介及中文手册

    - options域:设置ANTLR生成器的选项,如目标语言、编码等。 - lexer和parser规则:定义词法规则和语法规则,每个规则代表一种语言结构。 - parser规则通常用于构建语法树,lexer规则用于生成Token。 - tokens域:可...

    antlr4-json-parser.zip

    ANTLR4(ANother Tool for Language Recognition)是一款强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,如JSON解析器。ANTLR4可以生成Java、C#、...

    smt-antlr4-java-parser:该项目在构建时将生成 ANTLR4 Java 解析类

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,包括SQL解析器、XML处理器以及Java、C#和Python...

    antlr在.NET环境下的Runtime

    ANTLR( Anatomy of a Language Parser Generator )是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于构建语言、工具和框架,如SQL查询解析器、XML处理器、配置文件解析...

    利用Antlr实现的命令行解析器

    最后,`FCmd.tokens`是一个生成的文件,它包含了Antlr为识别的标记分配的唯一整数值。这些值在内部用于快速比较和处理标记。 总的来说,通过Antlr,我们可以高效地解析特定语法格式的命令行,实现自定义的命令行...

    smt-antlr4-javascript-parser:该项目在构建时将生成 ANTLR4 JavaScript 解析类

    ANTLR4 是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于各种编程语言的语法解析,包括但不限于Java、C#、Python、JavaScript等。在这个名为“smt-antlr4-javascript-...

    开源的语法分析工具Another Tool for Language Recognition

    4. **配置文件解析**:ANTLR可以用来解析复杂的配置文件格式,比如JSON、XML等。 5. **自然语言处理**:虽然主要应用于编程语言,但ANTLR也可以扩展用于自然语言处理领域。 #### 六、ANTLR的使用 - **安装**: ...

    Tucode:使用 ANTLR4 和 Java-Groovy 的小型编译器项目的存储库

    ANTLR4是一个强大的解析器生成器,广泛用于处理各种语言和格式,包括编程语言、查询语言、配置文件等。这个项目提供了一个很好的实践平台,帮助我们了解编译器设计的基本概念和技术。 首先,ANTLR4(ANother Tool ...

    c语法分析器

    6. `c.grm`: 这可能是描述C语言语法的语法文件,可能使用类似YACC或ANTLR的格式。语法文件定义了C语言的语法规则,用于指导解析过程。 7. `c_parser.h`, `c_main.h`, `c_lexer.h`: 这些是头文件,包含了对应源文件...

    词法语法分析器(JAVA)

    通过词法和语法分析,开发者可以实现自定义的代码检查、格式化和转换功能。 6. **自定义解析规则**: 开发者可以根据需求定制词法和语法规则,例如,创建一个新的DSL(Domain Specific Language)或者解析非标准...

    PracticaObligatoria

    在IT行业中,ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。这个“PracticaObligatoria”项目很可能是一个基于ANTLR的编程实践作业,旨在帮助学生深入理解ANTLR的工作原理及其...

Global site tag (gtag.js) - Google Analytics