- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在使用正则表达式来浏览一堆 Verilog 文件并提取某些语句。目前,正则表达式对此很合适,但是,我开始需要一个真正的解析器来处理嵌套结构,所以我正在研究 ocamllex/ocamlyacc。我想首先复制我的正则表达式实现中的内容,然后慢慢向语法中添加更多内容。
现在我主要对提取模块声明和实例化感兴趣。为了让这个问题更加简短,我们只看一下模块声明。
在 Verilog 中,模块声明如下所示:
module modmame ( ...other statements ) endmodule;
我当前的正则表达式实现只是检查是否有一个使用特定名称声明的模块(检查我感兴趣的名称列表 - 我不需要查找所有具有特定名称的模块声明)。所以基本上,我得到了我想要解析的 Verilog 文件的每一行,并进行如下匹配(带有 Pythonish 和 Rubyish 元素的伪 OCaml):
foreach file in list_of_files:
let found_mods = Hashtbl.create 17;
open file
foreach line in file:
foreach modname in modlist
let mod_patt= Str.regexp ("module"^space^"+"^modname^"\\("^space^"+\\|(\\)") in
try
Str.search_forward (mod_patt) line 0
found_mods[file] = modname; (* map filename to modname *)
with Not_found -> ()
效果很好。模块声明可以出现在 Verilog 文件中的任何位置;我只是想知道该文件是否包含该特定声明,我不关心该文件中还可能包含什么。
我第一次尝试将其转换为 ocamllex/ocamlyacc:
verLexer.mll:
rule lex = parse
| [' ' '\n' '\t'] { lex lexbuf }
| ['0'-'9']+ as s { INT(int_of_string s) }
| '(' { LPAREN }
| ')' { RPAREN }
| "module" { MODULE }
| ['A'-'Z''a'-'z''0'-'9''_']+ as s { IDENT(s) }
| _ { lex lexbuf }
| eof
verParser.mly:
%{ type expr = Module of expr | Ident of string | Int of int %}
%token <int> INT
%token <string> IDENT
%token LPAREN RPAREN MODULE EOF
%start expr1
%type <expr> expr1
%%
expr:
| MODULE IDENT LPAREN { Module( Ident $2) };
expr1:
| expr EOF { $1 };
然后在 REPL 中尝试一下:
# #use "verLexer.ml" ;;
# #use "verParser.ml" ;;
# expr1 lex (Lexing.from_string "module foo (" ) ;;
- : expr = Module (Ident "foo")
太棒了,它有效!
但是,真正的 Verilog 文件中不仅仅包含模块声明:
# expr1 lex (Lexing.from_string "//comment\nmodule foo ( \nstuff" ) ;;
Exception: Failure "lexing: empty token".
我并不真正关心模块定义之前或之后出现的内容,有没有办法提取那部分语法以确定 Verilog 文件包含“module foo (”语句?是的,我知道正则表达式对此工作得很好,但是,如上所述,我计划慢慢地发展这个语法并向其添加更多元素,正则表达式将开始崩溃。
编辑:我向 lex 规则添加了匹配任何字符:
| _ { lex lexbuf }
认为它会跳过迄今为止未匹配的任何字符,但这似乎不起作用:
# expr1 lex (Lexing.from_string "fof\n module foo (\n" ) ;;
Exception: Parsing.Parse_error.
最佳答案
第一个广告分钟:您应该考虑使用 François Pottier 的 Menhir 而不是 ocamlyacc
,就像“yacc,升级版”,在各个方面都更好(更易读的语法,更强大的结构,更容易调试......),同时仍然非常相似。它当然可以与ocamllex
结合使用。
您的 expr1
规则仅允许以 expr
规则开始和结束。您应该将其放大以允许在 expr
之前或之后添加“内容”。像这样的东西:
junk:
| junk LPAREN
| junk RPAREN
| junk INT
| junk IDENT
expr1:
| junk expr junk EOF
请注意,此语法不允许 module
标记出现在 junk
部分中。这样做会有点问题,因为它会使语法变得不明确(您正在寻找的结构可能嵌入在 expr
或 junk
中)。如果您可能在正在查找的表单之外出现 module
标记,则应考虑更改词法分析器以捕获整个 module ident(
感兴趣的结构) token ,以便它可以从语法中自动匹配。但是,从长远来看,拥有更细粒度的 token 可能会更好。
关于parsing - 使用 ocamllex/ocamlyacc 解析部分语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12062094/
我正在使用 ocamlyacc 和 ocamllex。我的语法中有一个错误产生,表示自定义异常。到目前为止,我可以让它报告错误位置: | error { raise (Parse_failure (s
在野牛中,添加就足够了 %verbose-error 到文件以使解析器错误更详细。有什么方法可以通过 ocamlyacc 获得类似的功能吗? Here是类似问题的答案,但我无法从中得出任何结论。这就是
我是 OCaml 新手,我正在尝试编写一个简单的类似 OCaml 的语法,但我无法弄清楚。我的语法允许这样的事情: let sub = fun x -> fun y -> x - y;; 但是,如果我
我在 expr.ml 文件中有一个 expr 类型。在 parser.mly(OCamlyacc 文件)中,我定义了 expr 规则并给出了类型: %start expr %type
我正在尝试培养一些词法分析/解析语法的技能。我回顾了我为 SQL 编写的一个简单解析器,我对它并不完全满意——似乎应该有一种更简单的方法来编写解析器。 SQL 让我很困惑,因为它有很多可选标记和重复。
我一直在使用正则表达式来浏览一堆 Verilog 文件并提取某些语句。目前,正则表达式对此很合适,但是,我开始需要一个真正的解析器来处理嵌套结构,所以我正在研究 ocamllex/ocamlyacc。
我使用 ocamlyacc 作为一个小型解析器,它还对大多数解析规则执行一些语义操作。 我在一开始就定义了一组标记: %token T_plus %token T_minus %token T_in
我有一个非常简单的代数表达式的数据类型(只有标识符、加法和乘法),我想将诸如“a + b * (c + d)”之类的字符串解析为这种类型。我的默认冲动是使用 Ulex+Menhir,但我想知道对于这样
是否可以为 OCamlYacc 生成的解析器提供显式 token 列表以进行分析? 我想使用 OCamlLex 显式生成一个 token 列表,然后我稍后使用 Yacc 生成的解析器对其进行分析。但是
我正在使用 F# 开发玩具编译器,即 FsLex 和 FsYacc 的组合。为了熟悉它们,我阅读了 Expert F# (v2) 一书(一本好书)的 Lexer/Parser 章节。现在,我已经完成了
我是一名优秀的程序员,十分优秀!