mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-03-16 17:00:53 +00:00
Merge pull request #353 from ayosec/outdir-280
Generate files in OUT_DIR
This commit is contained in:
commit
5766e5f3c2
47
.gitignore
vendored
47
.gitignore
vendored
@ -2,50 +2,3 @@ target
|
||||
*~
|
||||
TAGS
|
||||
lalrpop/src/parser/lrgrammar.rs
|
||||
|
||||
doc/calculator/src/calculator1.rs
|
||||
doc/calculator/src/calculator2.rs
|
||||
doc/calculator/src/calculator2b.rs
|
||||
doc/calculator/src/calculator3.rs
|
||||
doc/calculator/src/calculator4.rs
|
||||
doc/calculator/src/calculator5.rs
|
||||
doc/calculator/src/calculator6.rs
|
||||
doc/pascal/lalrpop/src/pascal.rs
|
||||
doc/whitespace/src/parser.rs
|
||||
|
||||
lalrpop-test/src/error.rs
|
||||
lalrpop-test/src/error_issue_113.rs
|
||||
lalrpop-test/src/error_issue_278.rs
|
||||
lalrpop-test/src/error_issue_261.rs
|
||||
lalrpop-test/src/error_recovery.rs
|
||||
lalrpop-test/src/error_recovery_pull_182.rs
|
||||
lalrpop-test/src/error_recovery_issue_240.rs
|
||||
lalrpop-test/src/error_recovery_lock_in.rs
|
||||
lalrpop-test/src/error_recovery_lalr_loop.rs
|
||||
lalrpop-test/src/error_recovery_span.rs
|
||||
lalrpop-test/src/error_recovery_type_in_macro.rs
|
||||
lalrpop-test/src/expr.rs
|
||||
lalrpop-test/src/expr_arena.rs
|
||||
lalrpop-test/src/expr_generic.rs
|
||||
lalrpop-test/src/expr_intern_tok.rs
|
||||
lalrpop-test/src/expr_lalr.rs
|
||||
lalrpop-test/src/expr_module_attributes.rs
|
||||
lalrpop-test/src/generics_issue_104.rs
|
||||
lalrpop-test/src/inline.rs
|
||||
lalrpop-test/src/intern_tok.rs
|
||||
lalrpop-test/src/issue_55.rs
|
||||
lalrpop-test/src/lifetime_tok.rs
|
||||
lalrpop-test/src/loc.rs
|
||||
lalrpop-test/src/loc_issue_90.rs
|
||||
lalrpop-test/src/sub.rs
|
||||
lalrpop-test/src/sub_ascent.rs
|
||||
lalrpop-test/src/sub_table.rs
|
||||
lalrpop-test/src/unit.rs
|
||||
lalrpop-test/src/use_super.rs
|
||||
lalrpop-test/src/no_clone_tok.rs
|
||||
lalrpop-test/src/partial_parse.rs
|
||||
lalrpop-test/src/match_alternatives.rs
|
||||
lalrpop-test/src/match_section.rs
|
||||
lalrpop-test/src/expr_module_attributes.rs
|
||||
lalrpop-test/src/associated_types.rs
|
||||
lalrpop-test/src/where_clause_with_forall.rs
|
||||
|
@ -1,6 +1,6 @@
|
||||
extern crate lalrpop_util;
|
||||
#[macro_use] extern crate lalrpop_util;
|
||||
|
||||
pub mod calculator1; // synthesized by LALRPOP
|
||||
lalrpop_mod!(pub calculator1); // syntesized by LALRPOP
|
||||
|
||||
#[test]
|
||||
fn calculator1() {
|
||||
@ -10,7 +10,7 @@ fn calculator1() {
|
||||
assert!(calculator1::TermParser::new().parse("((22)").is_err());
|
||||
}
|
||||
|
||||
pub mod calculator2;
|
||||
lalrpop_mod!(pub calculator2);
|
||||
|
||||
#[test]
|
||||
fn calculator2() {
|
||||
@ -20,7 +20,7 @@ fn calculator2() {
|
||||
assert!(calculator2::TermParser::new().parse("((22)").is_err());
|
||||
}
|
||||
|
||||
pub mod calculator2b;
|
||||
lalrpop_mod!(pub calculator2b);
|
||||
|
||||
#[test]
|
||||
fn calculator2b() {
|
||||
@ -37,7 +37,7 @@ fn calculator2b() {
|
||||
assert_eq!(result, "222");
|
||||
}
|
||||
|
||||
pub mod calculator3;
|
||||
lalrpop_mod!(pub calculator3);
|
||||
|
||||
#[cfg_attr(not(test), allow(unused_macros))]
|
||||
macro_rules! test3 {
|
||||
@ -56,7 +56,7 @@ fn calculator3() {
|
||||
test3!(22 * (44 + 66) / 3);
|
||||
}
|
||||
|
||||
pub mod calculator4;
|
||||
lalrpop_mod!(pub calculator4);
|
||||
pub mod ast;
|
||||
|
||||
#[test]
|
||||
@ -67,7 +67,7 @@ fn calculator4() {
|
||||
assert_eq!(&format!("{:?}", expr), "((22 * 44) + 66)");
|
||||
}
|
||||
|
||||
pub mod calculator5;
|
||||
lalrpop_mod!(pub calculator5);
|
||||
|
||||
#[test]
|
||||
fn calculator5() {
|
||||
@ -95,7 +95,7 @@ fn calculator5() {
|
||||
assert_eq!(&format!("{:?}", expr), "[((22 * 44) + 66), (13 * 3)]");
|
||||
}
|
||||
|
||||
pub mod calculator6;
|
||||
lalrpop_mod!(pub calculator6);
|
||||
|
||||
#[test]
|
||||
fn calculator6() {
|
||||
|
@ -3,7 +3,6 @@ extern crate lalrpop;
|
||||
fn main() {
|
||||
lalrpop::Configuration::new()
|
||||
.emit_comments(true)
|
||||
.use_cargo_dir_conventions()
|
||||
.process_current_dir()
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ extern crate docopt;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate serde;
|
||||
#[macro_use] extern crate lalrpop_util;
|
||||
|
||||
use docopt::Docopt;
|
||||
use std::env;
|
||||
@ -9,7 +10,7 @@ use std::io::Read;
|
||||
use std::fs::File;
|
||||
use std::time::Instant;
|
||||
|
||||
mod pascal;
|
||||
lalrpop_mod!(pascal);
|
||||
|
||||
fn main() {
|
||||
let args: Args = Docopt::new(USAGE)
|
||||
|
@ -14,6 +14,6 @@
|
||||
- [Error recovery](tutorial/008_error_recovery.md)
|
||||
- [Writing a custom lexer](lexer_tutorial/index.md)
|
||||
- [Advanced setup](advanced_setup.md)
|
||||
- [Using the Cargo `OUT_DIR`](out_dir.md)
|
||||
- [Generate in source tree](generate_in_source.md)
|
||||
-----------
|
||||
[Contributors](misc/contributors.md)
|
||||
|
19
doc/src/generate_in_source.md
Normal file
19
doc/src/generate_in_source.md
Normal file
@ -0,0 +1,19 @@
|
||||
Up to version 0.15, LALRPOP was generating its files in the same directory
|
||||
of the input files. Since 0.16, files are generated in the Cargo's
|
||||
**output directory**.
|
||||
|
||||
If you want to keep the previous behaviour, you can use `generate_in_source_tree`
|
||||
in your configuration:
|
||||
|
||||
```rust
|
||||
extern crate lalrpop;
|
||||
|
||||
fn main() {
|
||||
lalrpop::Configuration::new()
|
||||
.generate_in_source_tree()
|
||||
.process();
|
||||
}
|
||||
```
|
||||
|
||||
For each `foo.lalrpop` file you can simply have `mod foo;` in your source tree.
|
||||
The `lalrpop_mod` macro is not useful in this mode.
|
@ -1,24 +0,0 @@
|
||||
One common request is to have LALRPOP generate its files into Cargo's
|
||||
**output directory**, rather than storing them 'in-place' within the
|
||||
module tree. This can be done through the following configuration:
|
||||
|
||||
```rust
|
||||
extern crate lalrpop;
|
||||
|
||||
fn main() {
|
||||
lalrpop::Configuration::new()
|
||||
.use_cargo_dir_conventions()
|
||||
.process();
|
||||
}
|
||||
```
|
||||
|
||||
In addition, because the modules are generated out of the `src`
|
||||
directory, for each `foo.lalrpop` file you can't simply have `mod
|
||||
foo;` in your source. Instead, you must put the following in the
|
||||
parent module:
|
||||
|
||||
```rust
|
||||
include!(concat!(env!("OUT_DIR"), "/path/to/foo.rs"));
|
||||
```
|
||||
|
||||
Here the `path/to/foo.rs` should be relative to the `src` directory.
|
@ -101,7 +101,9 @@ our [`main.rs`][main] file which uses this struct to test our `Term`
|
||||
nonterminal:
|
||||
|
||||
```rust
|
||||
pub mod calculator1; // synthesized by LALRPOP
|
||||
#[macro_use] extern crate lalrpop_util;
|
||||
|
||||
lalrpop_mod!(pub calculator1); // synthesized by LALRPOP
|
||||
|
||||
#[test]
|
||||
fn calculator1() {
|
||||
|
@ -103,7 +103,9 @@ FactorOp: Opcode = {
|
||||
And, of course, we have to add some tests to [main.rs file][main]:
|
||||
|
||||
```rust
|
||||
pub mod calculator5;
|
||||
#[macro_use] extern crate lalrpop_util;
|
||||
|
||||
lalrpop_mod!(pub calculator5);
|
||||
|
||||
#[test]
|
||||
fn calculator5() {
|
||||
|
@ -1,8 +1,11 @@
|
||||
#[macro_use] extern crate lalrpop_util;
|
||||
|
||||
pub mod lexer;
|
||||
pub mod parser;
|
||||
pub mod ast;
|
||||
pub mod eval;
|
||||
|
||||
lalrpop_mod!(pub parser);
|
||||
|
||||
pub fn compile(input: &str) -> Result<ast::Program, String> {
|
||||
match parser::ProgramParser::new().parse(lexer::Lexer::new(input)) {
|
||||
Ok(s) => Ok(ast::Program::new(s)),
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(clippy))]
|
||||
grammar(scale: i32);
|
||||
|
||||
use util::tok::Tok;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![cfg_attr(not(test), allow(dead_code, unused_imports))]
|
||||
|
||||
extern crate diff;
|
||||
extern crate lalrpop_util;
|
||||
#[macro_use] extern crate lalrpop_util;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
@ -11,105 +11,105 @@ use util::tok::Tok;
|
||||
|
||||
/// Tests that actions can return the grammar's type parameters' associated
|
||||
/// types.
|
||||
mod associated_types;
|
||||
lalrpop_mod!(associated_types);
|
||||
mod associated_types_lib;
|
||||
|
||||
/// demonstration from the Greene text; one of the simplest grammars
|
||||
/// that still ensures we get parse tree correct
|
||||
mod sub;
|
||||
lalrpop_mod!(sub);
|
||||
|
||||
/// test something other than test-all
|
||||
mod sub_ascent;
|
||||
mod sub_table;
|
||||
lalrpop_mod!(sub_ascent);
|
||||
lalrpop_mod!(sub_table);
|
||||
|
||||
/// more interesting demonstration of parsing full expressions
|
||||
mod expr;
|
||||
lalrpop_mod!(expr);
|
||||
|
||||
/// more interesting demonstration of parsing full expressions, using LALR not LR
|
||||
mod expr_lalr;
|
||||
lalrpop_mod!(expr_lalr);
|
||||
|
||||
/// more interesting demonstration of parsing full expressions, using intern tok
|
||||
mod expr_intern_tok;
|
||||
lalrpop_mod!(expr_intern_tok);
|
||||
|
||||
/// tests #![attributes] for generated module
|
||||
#[allow(dead_code, unknown_lints)]
|
||||
mod expr_module_attributes;
|
||||
lalrpop_mod!(expr_module_attributes);
|
||||
|
||||
/// test that passes in lifetime/type/formal parameters and threads
|
||||
/// them through, building an AST from the result
|
||||
mod expr_arena;
|
||||
lalrpop_mod!(expr_arena);
|
||||
|
||||
/// definitions of the AST
|
||||
mod expr_arena_ast;
|
||||
|
||||
/// expr defined with a generic type `F`
|
||||
mod expr_generic;
|
||||
lalrpop_mod!(expr_generic);
|
||||
|
||||
mod generics_issue_104;
|
||||
lalrpop_mod!(generics_issue_104);
|
||||
mod generics_issue_104_lib;
|
||||
|
||||
/// Grammar parameterized by `F` with where clause `where F: for<'a> FnMut(&'a
|
||||
/// str)`.
|
||||
mod where_clause_with_forall;
|
||||
lalrpop_mod!(where_clause_with_forall);
|
||||
|
||||
/// test of inlining
|
||||
mod inline;
|
||||
lalrpop_mod!(inline);
|
||||
|
||||
/// test that exercises internal token generation, as well as locations and spans
|
||||
mod intern_tok;
|
||||
lalrpop_mod!(intern_tok);
|
||||
|
||||
/// test that exercises using a lifetime parameter in the token type
|
||||
mod lifetime_tok;
|
||||
lalrpop_mod!(lifetime_tok);
|
||||
|
||||
/// library for lifetime_tok test
|
||||
mod lifetime_tok_lib;
|
||||
|
||||
/// test that exercises locations and spans
|
||||
mod loc;
|
||||
lalrpop_mod!(loc);
|
||||
|
||||
/// regression test for location issue #90
|
||||
mod loc_issue_90;
|
||||
lalrpop_mod!(loc_issue_90);
|
||||
mod loc_issue_90_lib;
|
||||
|
||||
/// test that uses `super` in paths in various places
|
||||
mod use_super;
|
||||
lalrpop_mod!(use_super);
|
||||
|
||||
/// Custom error type (issue #113)
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct MyCustomError(char);
|
||||
|
||||
/// test that exercises locations, spans, and custom errors
|
||||
mod error;
|
||||
mod error_issue_113;
|
||||
lalrpop_mod!(error);
|
||||
lalrpop_mod!(error_issue_113);
|
||||
|
||||
/// Test error recovery
|
||||
mod error_recovery;
|
||||
mod error_recovery_pull_182;
|
||||
mod error_recovery_issue_240;
|
||||
mod error_recovery_lalr_loop;
|
||||
mod error_recovery_lock_in;
|
||||
mod error_recovery_span;
|
||||
mod error_recovery_type_in_macro;
|
||||
lalrpop_mod!(error_recovery);
|
||||
lalrpop_mod!(error_recovery_pull_182);
|
||||
lalrpop_mod!(error_recovery_issue_240);
|
||||
lalrpop_mod!(error_recovery_lalr_loop);
|
||||
lalrpop_mod!(error_recovery_lock_in);
|
||||
lalrpop_mod!(error_recovery_span);
|
||||
lalrpop_mod!(error_recovery_type_in_macro);
|
||||
|
||||
/// test for inlining expansion issue #55
|
||||
mod issue_55;
|
||||
lalrpop_mod!(issue_55);
|
||||
|
||||
/// test for unit action code
|
||||
mod unit;
|
||||
lalrpop_mod!(unit);
|
||||
|
||||
/// test for match section
|
||||
mod match_section;
|
||||
mod match_alternatives;
|
||||
lalrpop_mod!(match_section);
|
||||
lalrpop_mod!(match_alternatives);
|
||||
|
||||
/// regression test for issue #253.
|
||||
mod partial_parse;
|
||||
lalrpop_mod!(partial_parse);
|
||||
|
||||
/// regression test for issue #278.
|
||||
mod error_issue_278;
|
||||
lalrpop_mod!(error_issue_278);
|
||||
|
||||
// Check that error recovery (which requires cloneable tokens) is not created if it is not used
|
||||
#[allow(unused)]
|
||||
mod no_clone_tok;
|
||||
lalrpop_mod!(no_clone_tok);
|
||||
|
||||
mod util;
|
||||
|
||||
|
@ -143,6 +143,35 @@ pub struct ErrorRecovery<L, T, E> {
|
||||
pub dropped_tokens: Vec<(L, T, L)>,
|
||||
}
|
||||
|
||||
/// Define a module using the generated parse from a `.lalrpop` file.
|
||||
///
|
||||
/// You have to specify the name of the module and the path of the file
|
||||
/// generated by LALRPOP. If the input is in the root directory, you can
|
||||
/// omit it.
|
||||
///
|
||||
/// # Example
|
||||
/// ```ignore
|
||||
/// // load parser in src/parser.lalrpop
|
||||
/// lalrpop_mod!(parser);
|
||||
///
|
||||
/// // load parser in src/lex/parser.lalrpop
|
||||
/// lalrpop_mod!(parser, "/lex/parser.rs");
|
||||
///
|
||||
/// // define a public module
|
||||
/// lalrpop_mod!(pub parser);
|
||||
/// ```
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! lalrpop_mod {
|
||||
($modname:ident) => { lalrpop_mod!($modname, concat!("/", stringify!($modname), ".rs")); };
|
||||
|
||||
(pub $modname:ident) => { lalrpop_mod!(pub $modname, concat!("/", stringify!($modname), ".rs")); };
|
||||
|
||||
($modname:ident, $source:expr) => { mod $modname { include!(concat!(env!("OUT_DIR"), $source)); } };
|
||||
|
||||
(pub $modname:ident, $source:expr) => { pub mod $modname { include!(concat!(env!("OUT_DIR"), $source)); } };
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -76,6 +76,20 @@ impl Configuration {
|
||||
self
|
||||
}
|
||||
|
||||
/// Write output files in the same directory of the input files.
|
||||
///
|
||||
/// If this option is enabled, you have to load the parser as a module:
|
||||
///
|
||||
/// ```no_run
|
||||
/// mod parser; // synthesized from parser.lalrpop
|
||||
/// ```
|
||||
///
|
||||
/// This was the default behaviour up to version 0.15.
|
||||
pub fn generate_in_source_tree(&mut self) -> &mut Self {
|
||||
self.set_in_dir(Path::new("."))
|
||||
.set_out_dir(Path::new("."))
|
||||
}
|
||||
|
||||
/// If true, always convert `.lalrpop` files into `.rs` files, even if the
|
||||
/// `.rs` file is newer. Default is false.
|
||||
pub fn force_build(&mut self, val: bool) -> &mut Configuration {
|
||||
@ -149,7 +163,25 @@ impl Configuration {
|
||||
|
||||
/// Process all `.lalrpop` files in `path`.
|
||||
pub fn process_dir<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<Error>> {
|
||||
let session = Rc::new(self.session.clone());
|
||||
let mut session = self.session.clone();
|
||||
|
||||
// If in/out dir are empty, use cargo conventions by default.
|
||||
// See https://github.com/lalrpop/lalrpop/issues/280
|
||||
if session.in_dir.is_none() {
|
||||
let mut in_dir = try!(env::current_dir());
|
||||
in_dir.push("src");
|
||||
session.in_dir = Some(in_dir);
|
||||
}
|
||||
|
||||
if session.out_dir.is_none() {
|
||||
let out_dir = match env::var_os("OUT_DIR") {
|
||||
Some(var) => var,
|
||||
None => return Err("missing OUT_DIR variable")?,
|
||||
};
|
||||
session.out_dir = Some(PathBuf::from(out_dir));
|
||||
}
|
||||
|
||||
let session = Rc::new(session);
|
||||
try!(build::process_dir(session, path));
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user