Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

kibaamor/c0-parser

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

c0-parser

C0语言的词法分析和抽象语法树(AST)分析器

C0语言

C0是简化了C语言语法与编译过程得到的小型编程语言。在文档的最后有C0的完整文法定义。

保留了C中的:

  • 变量类型:int, char, double
  • 条件判断:if
  • 循环语句:for, while, do
  • 循环控制:break, continue
  • 输入输出:scan, print
  • 函数相关:return

目录主要结构

.
├── CMakeLists.txt ---------CMake配置文件
├── data -------------------用于测试的c0源文件
│   ├── func.c0 ------------测试函数
│   ├── helloworld.c0 ------最简单的程序
│   ├── loop.c0 ------------测试循环
│   └── var_decl.c0 --------测试变量声明
├── examples ---------------示例程序
│   ├── dump_token.cpp -----词法分析打印
│   └── rewrite_ast.cpp ----语法分析打印
├── LICENSE ----------------源码使用许可
├── README.md --------------本文件
├── scripts ----------------生成工程可以使用的脚本文件
├── src --------------------C0分析器和核心代码
└── test -------------------C0分析器测试代码

如何编译

需要的软件

  • Visual Studio 2015及以上(Windows)
  • Gcc 4.9.1 (Linux)
  • CMake 3.1及以上

编译步骤

打开命令行

# 下载源码
git clone https://github.com/KibaAmor/c0-parser.git

# 进入源码根目录
cd c0-parser

# 创建存放编译中间文件的目录
mkdir build

# 进入存放编译中间文件的目录
cd build

# 生成工程
cmake ..

# 编译工程
# Windows下直接用Visual Studio打开c0-parser.sln
c0-parser.sln
# Linux下使用下面的命令编译
make -j3

生成的可执行文件在存放编译中间文件的目录下面的bin文件夹中。

Windows下也可以运行源码根目录scripts目录下的gen_vs2015project.bat或者gen_vs2017project.bat来生成sln工程文件。

如何测试

Windows

在Visual Studio中编译工程中名为RUN_TESTS的项目,即可在Visual Studio的编译输出控制台中看到测试结果,也可以直接运行项目中test文件夹下的工程。

Linux

打开命令行

进入源码根目录
cd c-parser

# 进入存放编译中间文件的目录
cd build

# 运行所有测试
make test

附:完整的C0文法

<digit> ::= 
    '0'|<nonzero-digit>
<nonzero-digit> ::= 
    '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
<hexadecimal-digit> ::=
    <digit>|'a'|'b'|'c'|'d'|'e'|'f'|'A'|'B'|'C'|'D'|'E'|'F'

<integer-literal> ::= 
    <decimal-literal>|<hexadecimal-literal>
<decimal-literal> ::= 
    '0'|<nonzero-digit>{<digit>}
<hexadecimal-literal> ::= 
    ('0x'|'0X')<hexadecimal-digit>{<hexadecimal-digit>}


<nondigit> ::=    'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'|'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'

<identifier> ::= 
    <nondigit>{<nondigit>|<digit>}
<reserved-word> ::= 
     'const'
    |'void'   |'int'    |'char'   |'double'
    |'struct'
    |'if'     |'else'   
    |'switch' |'case'   |'default'
    |'while'  |'for'    |'do'
    |'return' |'break'  |'continue' 
    |'print'  |'scan'


<char-literal> ::= 
    "'" (<c-char>|<escape-seq>) "'" 
<string-literal> ::= 
    '"' {<s-char>|<escape-seq>} '"'
<escape-seq> ::=  
      '\\' | "\'" | '\"' | '\n' | '\r' | '\t'
    | '\x'<hexadecimal-digit><hexadecimal-digit>

    
<sign> ::= 
    '+'|'-'
<digit-seq> ::=
    <digit>{<digit>}
<floating-literal> ::= 
     [<digit-seq>]'.'<digit-seq>[<exponent>]
    |<digit-seq>'.'[<exponent>]
    |<digit-seq><exponent>
<exponent> ::= 
    ('e'|'E')[<sign>]<digit-seq>
   
    
<unary-operator>          ::= '+' | '-'
<additive-operator>       ::= '+' | '-'
<multiplicative-operator> ::= '*' | '/'
<relational-operator>     ::= '<' | '<=' | '>' | '>=' | '!=' | '=='
<assignment-operator>     ::= '='   

    
<single-line-comment> ::=
    '//'{<any-char>}<LF>
<multi-line-comment> ::= 
    '/*'{<any-char>}'*/'  
    
    
<type-specifier>         ::= <simple-type-specifier>
<simple-type-specifier>  ::= 'void'|'int'|'char'|'double'
<const-qualifier>        ::= 'const'
    
    
<C0-program> ::= 
    {<variable-declaration>}{<function-definition>}


<variable-declaration> ::= 
    [<const-qualifier>]<type-specifier><init-declarator-list>';'
<init-declarator-list> ::= 
    <init-declarator>{','<init-declarator>}
<init-declarator> ::= 
    <identifier>[<initializer>]
<initializer> ::= 
    '='<expression>    

    
<function-definition> ::= 
    <type-specifier><identifier><parameter-clause><compound-statement>

<parameter-clause> ::= 
    '(' [<parameter-declaration-list>] ')'
<parameter-declaration-list> ::= 
    <parameter-declaration>{','<parameter-declaration>}
<parameter-declaration> ::= 
    [<const-qualifier>]<type-specifier><identifier>

    
<compound-statement> ::= 
    '{' {<variable-declaration>} <statement-seq> '}'
<statement-seq> ::= 
    {<statement>}
<statement> ::= 
     <compound-statement>
    |<condition-statement>
    |<loop-statement>
    |<jump-statement>
    |<print-statement>
    |<scan-statement>
    |<assignment-expression>';'
    |<function-call>';'
    |';'   
    
    
<condition> ::= 
     <expression>[<relational-operator><expression>] 
   
<condition-statement> ::= 
     'if' '(' <condition> ')' <statement> ['else' <statement>]
    |'switch' '(' <expression> ')' '{' {<labeled-statement>} '}'

<labeled-statement> ::= 
     'case' (<integer-literal>|<char-literal>) ':' <statement>
    |'default' ':' <statement>

    
<loop-statement> ::= 
    'while' '(' <condition> ')' <statement>
   |'do' <statement> 'while' '(' <condition> ')' ';'
   |'for' '('<for-init-statement> [<condition>]';' [<for-update-expression>]')' <statement>

<for-init-statement> ::= 
    [<assignment-expression>{','<assignment-expression>}]';'
<for-update-expression> ::=
    (<assignment-expression>|<function-call>){','(<assignment-expression>|<function-call>)}


<jump-statement> ::= 
     'break' ';'
    |'continue' ';'
    |<return-statement>
<return-statement> ::= 'return' [<expression>] ';'
    
    
<scan-statement> ::= 
    'scan' '(' <identifier> ')' ';'
<print-statement> ::= 
    'print' '(' [<printable-list>] ')' ';'
<printable-list>  ::= 
    <printable> {',' <printable>}
<printable> ::= 
    <expression> | <string-literal>

<assignment-expression> ::= 
    <identifier><assignment-operator><expression>
    
   
  
<expression> ::= 
    <additive-expression>
<additive-expression> ::= 
     <multiplicative-expression>{<additive-operator><multiplicative-expression>}
<multiplicative-expression> ::= 
     <cast-expression>{<multiplicative-operator><cast-expression>}
<cast-expression> ::=
    {'('<type-specifier>')'}<unary-expression>
<unary-expression> ::=
    [<unary-operator>]<primary-expression>
<primary-expression> ::=  
     '('<expression>')' 
    |<identifier>
    |<integer-literal>
    |<char-literal>
    |<floating-literal>
    |<function-call>

<function-call> ::= 
    <identifier> '(' [<expression-list>] ')'
<expression-list> ::= 
    <expression>{','<expression>}

About

C0语言的词法分析和抽象语法树(AST)分析器

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.