项目作者: izuzanak

项目描述 :
Rapid prototyping parser generator
高级语言: C++
项目地址: git://github.com/izuzanak/yapgen.git
创建时间: 2015-05-21T15:52:56Z
项目社区:https://github.com/izuzanak/yapgen

开源协议:GNU General Public License v2.0

下载


yapgen - parser generator

Build Status
CI

Rapid prototyping parser generator.

Parser generator features

Follows list of parser generator features.

Feature list

  • Generates parser lexical and syntactical analyzers based on input file.
  • Lexical symbols are described by regular expressions.
  • Language grammar is described by SLR(1) grammar.
  • Generated parser can be immediately tested on source string.
  • Semantic rules of language can be tested by Lua scripts, that are binded to
    each rule reduction.
  • Debugged and fine tuned parser can be generated in form of C/C++ code.

Motivation

Need for fast parser generation and testing.

Rule examples

Examples of rule files used to generate parsers are placed in directory:
build/rules

Inline examples

Follows few simple examples demonstrating yapgen possibilities.

Regular expressions

Examples of basic regular expressions.

  1. oct_int {'0'.<07>*}
  2. dec_int {<19>.d*}
  3. hex_int {'0'.[xX].(<09>+<af>+<AF>).(<09>+<af>+<AF>)*}
  4. if {"if"}
  5. else {"else"}
  6. equal {'='}
  7. plus_equal {"+="}
  8. minus_equal {"-="}
  9. comment_sl {"//".!'\n'*.'\n'}
  10. comment_ml {"/*".(!'*'+('*'.!'/'))*."*/"}

Regular expressions can be used to recognize binary data.

  1. PACKET_ADDRESS {"/?".(<09>+<az>+<AZ>)*.'!'."\x0d\x0a"}
  2. PACKET_IDENTIFY {'/'.<AZ>.<AZ>.(<AZ>+<az>).<09>.(|/!\x0d|)*."\x0d\x0a"}
  3. PACKET_ACK_COMMAND {'\x06'.<09>.(<09>+<az>).<09>."\x0d\x0a"}
  4. PACKET_ACK {'\x06'}

Grammar rules

Example of basic grammar rules. Identifiers closed in angle (sharp) brackets
e.g. <command> identifies nonterminal symbols of grammar, and identifiers
without brackets e.g. if refers to terminal symbols described by regular
expressions.

  1. <command> -> if <condition> <if_else> ->> {}
  2. <if_else> -> <command> ->> {}
  3. <if_else> -> <command> else <command> ->> {}
  4. <command> -> <while_begin> <condition> <command> ->> {}
  5. <while_begin> -> while ->> {}

Grammar rules can have semantic code binded to them.

  1. <F> -> <F> double_equal <E> ->>
  2. {
  3. if gen_parse_tree == 1 then
  4. this_idx = node_idx;
  5. node_idx = node_idx + 1;
  6. print(" node_"..this_idx.." [label = \"<exp> == <exp>\"]");
  7. print(" node_"..this_idx.." -> node_"..table.remove(node_stack).."");
  8. print(" node_"..this_idx.." -> node_"..table.remove(node_stack).."");
  9. table.insert(node_stack,this_idx);
  10. else
  11. print(table.concat(tabs,"").."operator binary double_equal");
  12. end
  13. }

Parser rule file

Follows example of complete parser rules file.

  1. init_code: {s = {\};}
  2. terminals:
  3. oct_int_const {'0'.<07>*}
  4. dec_int_const {<19>.d*}
  5. hex_int_const {'0'.[xX].(<09>+<af>+<AF>).(<09>+<af>+<AF>)*}
  6. lr_br {'('}
  7. rr_br {')'}
  8. plus {'+'}
  9. minus {'-'}
  10. asterisk {'*'}
  11. slash {'/'}
  12. percent {'%'}
  13. _SKIP_ {w.w*}
  14. _END_ {'\0'}
  15. nonterminals:
  16. <start> <exp> <C> <B> <A>
  17. rules:
  18. <start> -> <exp> _END_ ->> {}
  19. <exp> -> <C> ->> {print("result: "..s[#s]);}
  20. <C> -> <C> plus <B> ->> {s[#s-1] = s[#s-1] + table.remove(s);}
  21. <C> -> <C> minus <B> ->> {s[#s-1] = s[#s-1] - table.remove(s);}
  22. <C> -> <B> ->> {}
  23. <B> -> <B> asterisk <A> ->> {s[#s-1] = s[#s-1] * table.remove(s);}
  24. <B> -> <B> slash <A> ->> {s[#s-1] = s[#s-1] / table.remove(s);}
  25. <B> -> <B> percent <A> ->> {s[#s-1] = s[#s-1] % table.remove(s);}
  26. <B> -> <A> ->> {}
  27. <A> -> lr_br <C> rr_br ->> {}
  28. <A> -> oct_int_const ->> {table.insert(s,tonumber(rule_body(0),8));}
  29. <A> -> dec_int_const ->> {table.insert(s,tonumber(rule_body(0),10));}
  30. <A> -> hex_int_const ->> {table.insert(s,tonumber(rule_body(0)));}

Parser generated from presented rule string will generate following result
for following input string.

  1. 5*(10 + 5) - 0x10
  1. result: 59

Building parser generator

Programming language Lua of version 5.2 or greater
is required for yapgen compilation.

The container generator cont is needed
for compilation of parser generator.

Linux compilation

Enter build directory build.

  1. cd build

Process cmake source.

  1. cmake ..

Build yapgen.

  1. make -j$(nproc)

Linux example parsers

Example parsers are located in directory
build/rules.